我需要执行自动完成功能,需要执行以下操作:
select field from huge_table where field like '%some string%';
该表是200万行,我需要快速和多个响应。 我们正在使用Postgres。而这种查询将永远存在。
使用postgres有一种有效的方法吗?或者我应该使用除postgres以外的其他东西吗?
谢谢!
答案 0 :(得分:2)
如果您正在进行自动填充,我假设您正在寻找基于前缀的匹配项。基于前缀的查找的标准数据结构是trie。
如果使用索引和基于前缀的查找(some string%
)无法从postgres获得足够的性能,您可以定期对所有200万行进行完整查询,并构建一个trie或保留一个与数据库并行。
Trie的最差情况表现为O(m)
,其中m
是您的前缀的长度,因此一旦构建,它将提供非常快速自动完成。
答案 1 :(得分:1)
您可以为正在搜索的field
添加索引。
此外,如果可以避免,请不要使用像%some string%
这样的开放式通配符,以便真正伤害性能。如果可能,请执行some string%
。
答案 2 :(得分:1)
如果您能够支付额外的插入/更新时间,也可以使用the pg_trgm extension
您在该链接中进行了一些测试,其中有200万条记录表,以便在最佳情况下看到改进。
答案 3 :(得分:1)
根据您的用例的具体情况,可能值得知道tsquery
具有查询单词前缀的语法。将其与索引tsvector
字段相结合,您可以非常快速地查找字前缀。
创建“巨大”表:
CREATE TABLE huge_table (
field text,
field_tsv tsvector
);
添加索引:
CREATE INDEX field_tsv_idx ON huge_table USING gin(field_tsv);
添加触发器以更新索引列:
CREATE TRIGGER tsvectorupdate BEFORE INSERT OR UPDATE
ON huge_table FOR EACH ROW EXECUTE PROCEDURE
tsvector_update_trigger(field_tsv, 'pg_catalog.english', field);
添加一些模拟数据
INSERT INTO huge_table (field) VALUES ('something nice');
INSERT INTO huge_table (field) VALUES ('another thing');
然后查询具有某种限制的前缀:
SELECT field FROM huge_table WHERE field_tsv @@ to_tsquery('anot:*') LIMIT 20;
field
---------------
another thing
(1 row)
详细了解docs,尤其是index types,因为您的索引可能会非常大。