You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在多列索引中结合LEFT与LOWER实现前缀文本匹配?

PostgreSQL索引未完整利用问题排查

创建的索引

CREATE INDEX rep_tval_idx ON public.rep USING btree (t, lower(left(val, 127)));

执行的查询语句

EXPLAIN ANALYZE
select * from rep
where t=3 and lower(left(val, 127)) like 'operation%';

小表的执行计划(索引未完整利用)

Index Scan using rep_tval_idx on rep  (cost=0.14..3.67 rows=1 width=56) (actual time=0.044..0.045 rows=0 loops=1)
  Index Cond: (t = 3)
  Filter: (lower("left"(val, 127)) ~~ 'operation%'::text)
  Rows Removed by Filter: 16
Planning Time: 0.112 ms
Execution Time: 0.069 ms

表结构

CREATE TABLE public.rep (
    id bigserial NOT NULL,
    up int8 NOT NULL,
    t int8 NOT NULL,
    val text NULL,
    CONSTRAINT rep_pk PRIMARY KEY (id)
);

CREATE INDEX rep_tval_idx ON public.rep USING btree (t, lower("left"(val, 127)));
CREATE INDEX rep_upt_idx ON public.rep USING btree (up, t);

问题根源与验证

单独使用LOWER或LEFT时索引可正常工作,但测试时仅t=3的条件用到了索引,lower(left(val,127)) like 'operation%'被当作过滤条件而非索引条件。

后续验证发现:问题出在测试用的是小表(仅125行)。当使用大表(310466行)时,索引按预期完整生效,执行计划如下:

Index Scan using rep_tval_idx on rep  (cost=0.42..121.50 rows=120 width=56) (actual time=0.028..0.037 rows=8 loops=1)
  Index Cond: ((t = 3) AND (lower("left"(val, 127)) >= 'operation'::text) AND (lower("left"(val, 127)) < 'operatioo'::text))
  Filter: (lower("left"(val, 127)) ~~ 'operation%'::text)
Planning Time: 0.102 ms
Execution Time: 0.064 ms

内容的提问来源于stack exchange,提问作者Alexey Sam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 01:30:08