0

我有一个包含客户数据的表,它有 1200 万多条记录。我想根据几个字段来查询它,例如:first_name、last_name、birth_place。但是数据真的很脏,所以我想要甚至不完全匹配的记录。我为此使用了 unaccent 和 pg_trgm 模块。

我按照这个问题能够在索引中使用 unaccent,因此f_unaccent()而不是unaccent()在查询中。

指数:

CREATE INDEX first_name_idx ON customer USING gist(f_unaccent(coalesce(first_name, '')) gist_trgm_ops);
CREATE INDEX last_name_idx ON customer USING gist(f_unaccent(coalesce(last_name, '')) gist_trgm_ops);
CREATE INDEX birthplace_idx ON customer USING gist(f_unaccent(coalesce(birthplace, '')) gist_trgm_ops);

选择:

WITH t AS (
SELECT id, first_name, f_unaccent(coalesce(first_name, '')) <-> unaccent('Oliver') as first_name_distance, 
    last_name, f_unaccent(coalesce(last_name, '')) <-> unaccent('Twist') as last_name_distance,
    birthplace, f_unaccent(coalesce(birthplace, '')) <-> unaccent('London') as birthplace_distance, 
    FROM customer
),
s AS (
SELECT t.id, t.first_name_distance + t.last_name_distance + t.birthplace_distance as total FROM t
)

select * from t join s on (t.id = s.id);

当我对其运行分析时,它会进行顺序扫描。它不使用索引。我知道第一个选择在整个桌子上运行,所以也许很好。我使用的是<->,而不是similarity(text, text)函数,因为我什至想要一些字段相似度为 0 的记录,相似度之和是我关心的。

在真实数据上,这个查询(有 6 个字段,而不是 3 个)大约需要 12 分钟(没有索引,我没有创建它们,因为我在测试数据上看到它们甚至没有被使用......)

我怎样才能使这个查询运行得更快?谢谢

4

1 回答 1

1

由于查询从 获取所有customer,因此使用顺序扫描是最快的选择。

于 2018-03-20T15:31:06.810 回答