6

我需要做一个自动完成功能,需要做这样的事情:

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

该表有 200 万行,我需要它的快速响应和多个响应。我们正在使用 Postgres。这种查询将永远持续下去。

有没有一种有效的方法来使用 postgres 做到这一点?或者也许我应该使用 postgres 以外的其他东西?

谢谢!

4

4 回答 4

3

如果您正在执行自动完成,我假设您正在查找基于前缀的匹配项。基于前缀的查找的标准数据结构是trie

如果使用索引和基于前缀的查找some string%

Trie 的最坏情况是O(m),其中m是前缀的长度,因此一旦构建,它将提供非常快速的自动完成功能。

于 2013-03-28T21:06:35.450 回答
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)

阅读有关文档的更多信息,尤其是索引类型,因为您的索引可能会变得非常大。

于 2013-03-28T23:01:56.970 回答
1

您可以为field正在搜索的内容添加索引。

此外,如果可以避免,请不要使用开放式通配符,因为%some string%它们确实会损害性能。如果可能的话,做some string%

于 2013-03-28T20:59:44.360 回答
1

如果您负担得起额外的插入/更新时间,也许您可​​以使用pg_trgm 扩展

您在该链接中使用 200 万条记录表进行了一些测试,以查看最佳情况下的改进。

于 2013-03-28T21:13:56.470 回答