在我的查询中,我想找到与许多LIKE运算符之一匹配的行.我知道3种方法,但只有其中一种可以使用索引.
让我们从表开始:
CREATE TABLE dir (
id BIGSERIAL PRIMARY KEY,
path TEXT NOT NULL
);
CREATE INDEX path_idx ON dir(path TEXT_pattern_ops);
插入样本数据后,我可以这样做:
EXPLAIN ANALYZE
SELECT id, path FROM dir
WHERE path LIKE 'A%'
OR path LIKE 'B%'
OR path LIKE 'C%';
以上查询正确使用索引.
第二种方式:
EXPLAIN ANALYZE
SELECT id, path FROM dir
WHERE path LIKE ANY(ARRAY['A%', 'B%', 'C%']::TEXT[]);
此查询不会使用索引.
最后一种方法我知道:
CREATE TABLE patterns (pattern) AS VALUES
('A%'),
('B%'),
('C%');
EXPLAIN ANALYZE
SELECT id, path FROM dir
JOIN patterns ON (dir.path LIKE patterns.pattern);
像前一个查询的查询将不使用索引.
对于那些想要使用这些查询的人来说,这是SQL Fiddle:http://sqlfiddle.com/#!17/24031/2
问题:路径LIKE X或路径LIKE Y的查询对于许多模式是完全不可读的(模式的数量可能从几个到几百个或几千个不等),我担心大的查询可能很慢解析甚至达到1GB的限制查询长度(某些模式可能有很长的前缀).
问题:是否有任何oder方法返回相同的结果,不需要将所有模式直接放入查询中(如此选项中的连接)?
最佳答案 您可以创建支持查询的trigram索引.
为此你需要pg_trgm扩展名;以超级用户身份运行以下命令:
CREATE EXTENSION pg_trgm;
然后你可以创建一个GIN索引:
CREATE INDEX ON dir USING gin (path gin_trgm_ops);
这个索引可以用你的第二个和第三个方法,所以它应该为你做的伎俩.
对于像示例中的短模式,索引将不会非常有效.
您还可以使用GiST索引,该索引可能更小,但搜索速度更慢.
请注意,您也可以将该索引与以%开头的模式一起使用.