TiDB索引

【TiDB 使用环境】测试
【TiDB 版本】5.7.25-TiDB-v6.5.1
【操作系统】CentOS 7
【部署方式】机器部署(16C/64G)
【集群数据量】10W
【集群节点数】3
【问题复现路径】对SQL进行explain分析
【遇到的问题:问题现象及影响】表中存在联合索引(hash,record_time,item_id,thres_path),执行SELECT * FROM alert_history WHERE hash = xxx AND number = xxx AND target_id = xx , 为什么不会命中这个联合索引的hash列上?
【资源配置】进入到 TiDB Dashboard -集群信息 (Cluster Info) -主机(Hosts) 截图此页面
【复制黏贴 ERROR 报错的日志】
【其他附件:截图/日志/监控】


1 个赞

看看表健康度怎么样

explain analyze 语句 这样执行看看呢。


一样的

用hint语法指定索引,看看执行计划是怎么样的?这个hash字段是字符类型么?

表里一共多少条数据,hash=xxx有多少条数据

破案了,应该是这个hash对应的数据有点多,换了一个hash的值之后,就可以了。

嗯,表里一共2w多数据,这个hash对应的数据有几千条,太多了,没什么区分度了。

那这个联合索引就有待商榷了,可能不是很好。

:thinking:那为什么执行计划里actRows是2?应该是只有2条吧。

:thinking:就算有几千条,我觉得也应该走索引。

1 个赞

逐个where条件查询下数据量,选择查询结果最少及区分度最高的作为联合索引的第一个

2条是因为加了其他过滤条件。他这个条件只有一个hash字段能满足前缀。本身数量不多的话,hash字段过滤超过一定百分比就默认走全扫了。

1 个赞

因该是根据number条件做了过滤之后,只剩下了2个。

1 个赞

这个百分比是多少啊

1 个赞

表中存在联合索引(hash,record_time,item_id,thres_path),执行SELECT * FROM alert_history WHERE hash = xxx AND number = xxx AND target_id = xx 。。感觉这个SQL最多用到联合索引的前缀索引。。是否走了更好的联合索引

1 个赞

NDV是不是低了,如果提取的数据总量低于20%,可能就不走索引了吧

number和 target_id不在索引中,且它们出现在 record_time之前,导致索引只能使用到 hash列,后续列无法利用索引

可能是索引+回表的代价大于全表扫描的代价了