You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用多个LIKE运算符并让查询有效利用索引?

如何在PostgreSQL中高效查询匹配多个LIKE条件的行(利用索引)

嘿,关于用多个LIKE条件查数据还得蹭上索引这件事,我刚好有实战经验——你说的三种写法里,确实只有一种能让PostgreSQL乖乖用上咱们建的索引。咱们一步步来聊:

先搭好测试环境

首先得把表和索引建好,这里的关键是TEXT_pattern_ops索引,它是PostgreSQL里让TEXT类型的前缀LIKE查询能用上索引的核心:

CREATE TABLE dir (
  id BIGSERIAL PRIMARY KEY,
  path TEXT NOT NULL
);

-- 这个索引是前缀LIKE能走索引的前提
CREATE INDEX path_idx ON dir(path TEXT_pattern_ops);

1. 唯一能利用索引的写法:OR连接多个前缀LIKE

直接用OR把每个LIKE '前缀%'的条件连起来,PostgreSQL的查询优化器能精准识别这种模式,直接命中咱们建的索引:

EXPLAIN ANALYZE SELECT id, path FROM dir 
WHERE path LIKE 'A%' OR path LIKE 'B%' OR path LIKE 'C%';

跑一下EXPLAIN ANALYZE你就能看到,计划里明确用到了path_idx索引,数据量大的时候性能提升特别明显——因为索引直接帮咱们过滤掉了大部分不符合前缀的行,不用全表扫描。

2. 踩坑写法1:用LIKE ANY(ARRAY[])

很多人为了简化代码会这么写:

EXPLAIN ANALYZE SELECT id, path FROM dir 
WHERE path LIKE ANY(ARRAY['A%', 'B%', 'C%']);

看起来清爽,但可惜的是,PostgreSQL目前的优化器还没法把这种写法转换成能利用前缀索引的执行计划,只能走全表扫描,数据多的时候卡到怀疑人生。

3. 踩坑写法2:正则表达式前缀匹配

还有人会用正则来实现类似逻辑,比如:

EXPLAIN ANALYZE SELECT id, path FROM dir 
WHERE path ~ '^[ABC]';

逻辑上和之前的OR写法完全一致,但优化器不会把这种正则前缀匹配和TEXT_pattern_ops索引关联起来,同样只能全表扫,性能拉胯。

最后划重点

  • 只有多个OR连接的前缀LIKE条件LIKE 'X%')能触发TEXT_pattern_ops索引的使用
  • 后缀匹配('%X')或全模糊匹配('%X%')不管用哪种写法都没法用索引,这种场景要么接受全表扫,要么考虑用全文检索之类的其他方案
  • 别图省事用LIKE ANY或者正则前缀,这些都没法蹭到索引的红利

内容的提问来源于stack exchange,提问作者Michał Albrycht

火山引擎 最新活动