有索引为什么不走索引,反而走全表扫描呢?

【 使用环境 】测试环境
【 OB or 其他组件 】OceanBase‑ce,obclient
【 使用版本 】4.2.5‑ce
【问题描述】MySQL 模式租户,执行一条带 local 本地索引的 update 语句,执行计划走全表扫描,没有使用已创建的 local 索引,SQL 执行耗时很高。
【复现路径】

  1. 创建分区表,按 hash (c1) 分为 4 个分区
  2. 在 c2 字段建立 local 本地索引
  3. 执行 update t set c3=‘test’ where c2=100;
  4. explain 查看执行计划,算子为 TABLE FULL SCAN,没有走 TABLE RANGE SCAN 索引扫描。
create table t(c1 int,c2 int,c3 varchar(100)) partition by hash(c1) partitions 4;
create index idx_t_c2 on t(c2) local;
update t set c3='test' where c2=100;
explain update t set c3='test' where c2=100;
3 个赞

Local 本地索引,没有分区键过滤时,优化器必须扫描全部 4 个分区的索引表按hash(c1)分成 4 个分区,idx_t_c2是 local 索引:每个分区 P0/P1/P2/P3 各自维护一份c2的索引。where 只有c2=100,不知道 c1 的值,无法裁剪分区(partition pruning 分区裁剪失效)。
要找到c2=100的数据,理论上要遍历:P0 索引 → P1 索引 → P2 索引 → P3 索引,4 个分区索引全部查找。

1 个赞

考虑加个索引 。

66666