如何使用多个LIKE运算符并使用索引

时间:2018-05-02 11:21:26

标签: sql postgresql query-optimization sql-like

在我的查询中,我希望找到与许多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小提琴:http://sqlfiddle.com/#!17/24031/2

问题:对于许多模式,path LIKE X OR path LIKE Y的查询完全无法读取(模式数量可能从几个到几百个或几千个不等),我担心大型查询可能会很慢解析甚至达到1GB的查询长度限制(某些模式可能有很长的前缀)。

问题:是否有任何oder方法返回相同的结果,不需要将所有模式直接放入查询中(如此选项中的连接)?

1 个答案:

答案 0 :(得分:1)

您可以创建支持查询的三元组索引。

为此你需要pg_trgm扩展名;以超级用户身份运行以下命令:

CREATE EXTENSION pg_trgm;

然后你可以创建一个GIN索引:

CREATE INDEX ON dir USING gin (path gin_trgm_ops);

这个索引可以用你的第二个和第三个方法,所以它应该为你做的。

对于像示例中那样的短模式,索引不会非常有效。

您还可以使用GiST索引,该索引可能更小,但搜索速度更慢。

请注意,您也可以将该索引与以%开头的模式一起使用。