自动完成从巨大的表中获取数据

时间:2013-03-28 20:55:53

标签: sql database postgresql autocomplete

我需要执行自动完成功能,需要执行以下操作:

select field from huge_table where field like '%some string%';

该表是200万行,我需要快速和多个响应。 我们正在使用Postgres。而这种查询将永远存在。

使用postgres有一种有效的方法吗?或者我应该使用除postgres以外的其他东西吗?

谢谢!

4 个答案:

答案 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,因为您的索引可能会非常大。