前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >为什么范围后索引会失效 存储引擎不能使用索引中范围条件右边的列

为什么范围后索引会失效 存储引擎不能使用索引中范围条件右边的列

作者头像
JavaEdge
发布2022-02-23 15:25:15
2.1K0
发布2022-02-23 15:25:15
举报
文章被收录于专栏:JavaEdge

比如说有三个字段 a b c,建立复合索引a_b_c。此时叶子节点的数据排序后可能为

代码语言:javascript
复制
(a=1 b=1 c=1) (a=1 b=2 c=1) (a=1 b=2 c=3)
(a=2 b=2 c=3) (a=2 b=2 c=5) (a=2 b=5 c=1) (a=2 b=5 c=2)
(a=3 b=0 c=1) (a=3 b=3 c=5) (a=3 b=8 c=6)

查找

代码语言:javascript
复制
select a,b,c from table where a = 2 and b = 5 and c = 2

先根据a = 2找到第二行的四条数据

代码语言:javascript
复制
(a=2 b=2 c=3) (a=2 b=2 c=5) (a=2 b=5 c=1) (a=2 b=5 c=2)

然后根据b=5查到两条

代码语言:javascript
复制
(a=2 b=5 c=1) (a=2 b=5 c=2)

最后根据c=2查到目标数据

代码语言:javascript
复制
(a=2 b=5 c=2)

现在使用了范围条件

代码语言:javascript
复制
select a,b,c from table where a = 2 and b >1 and c = 2

先根据a = 2找到第二行的四条数据

代码语言:javascript
复制
(a=2 b=2 c=3) (a=2 b=2 c=5) (a=2 b=5 c=1) (a=2 b=5 c=2)

然后根据b>1查到四条数据

代码语言:javascript
复制
(a=2 b=2 c=3) (a=2 b=2 c=5) (a=2 b=5 c=1) (a=2 b=5 c=2)

此时要查找c=2了,但发现四条数据的c分别是3,5,1,2无序!所以索引失效!

总结

因为前一个条件相同的情况下 当前条件才会是有序的。当前一个条件不同 那么无法保证当前条件为有序的 所以索引失效

再进一步,假设有以下数据

代码语言:javascript
复制
1(b=2,c=4)
2(b=2,c=5)
3(b=3,c=1)
4(b=3,c=2)

此时对于b 这四个数据都是有序的。 但对于c 只有(1,2)和(3,4)两组数据内部分别有序,如果想让他有序 则需要进行再一次的排序。但是排序的时间复杂度高于遍历数据的时间复杂度 ps:再慢也不会慢过o(n),所以会直接遍历所有数据索引失效。

至于为什么在c后面的索引也会失效(范围后全失效),难道不能查完c之后,把c的结果当成索引继续吗? 再举一组例子 假设有以下数据

代码语言:javascript
复制
1(b=1,c=4,d = 10)
2(b=2,c=5,d = 6)
3(b=2,c=5,d = 7)
4(b=3,c=1,d = 2)
5(b=3,c=5,d = 1)

查找 b>1且 c = 5,d=6,先查出 b>1:

代码语言:javascript
复制
2(b=2,c=5,d = 6)
3(b=2,c=5,d = 7)
4(b=3,c=1,d = 2)
5(b=3,c=5,d = 1)

此时索引失效了。遍历一次结果(假设只对比c的值,这样更快)找到三条数据 c = 5:

代码语言:javascript
复制
2(b=2,c=5,d = 6)
3(b=2,c=5,d = 7)
5(b=3,c=5,d = 1)

这时候发现要查找字段d还是乱的,继续o(n)。 综上所述,范围后的查询字段都不是有序的,所以索引都失效了。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022/02/21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档