Mysql

关注公众号 jb51net

关闭
首页 > 数据库 > Mysql > MySQL联合索引范围条件失效

MySQL的联合索引范围条件失效问题解决办法

作者:Famiglistimo_123

在数据库优化中,索引是一项至关重要的技术手段,可以显著提升查询性能,下面这篇文章主要介绍了MySQL的联合索引范围条件失效问题解决的相关资料,文中介绍的非常非常详细,需要的朋友可以参考下

联合索引的排序逻辑:

非等值的范围条件:

范围条件对索引的影响:

举例

假设数据如下:

(name='张三', age=20, score=85)
(name='张三', age=20, score=90)
(name='张三', age=22, score=80)
(name='李四', age=19, score=95)
(name='李四', age=21, score=88)

情况一:

select * from student where name='张三' and age=20 and score=90;

情况二:

select * from student where name='张三' and age>20 and score=80;

情况三:

select * from student where name='张三' and age>20 and score=80;

为辅助理解,这里补充说明:若查询条件为where name='张三' and age>=20,age>20的部分索引仍会失效,只有age=20的部分查找时可以用到索引。

总结

>=、<= 能保留 “前缀等值部分的有序性”,而 >、< 会破坏边界的等值连续性,导致索引选择性更差,甚至完全失效。尽量使用大于等于(>=)或小于等于(<=)。

注意事项补充

  1. 单列索引无此问题:只有联合索引才有 “左侧 / 右侧列” 的概念,单列索引无论用 >、< 还是 >=、<=,都能正常利用索引;
  2. in 不算非等值范围条件in 是 “等值多值查询”,比如 name in ('张三', '李四') and age=20age 仍能利用索引(因为 name 虽多值但仍是等值匹配,age 排序有效);
  3. 范围列尽量放联合索引右侧:设计联合索引时,若一定要用到非等值范围条件,应将用非等值范围条件的列放在最后,避免影响左侧列的索引可用性;
  4. 覆盖索引可缓解失效影响:如果查询的列都在联合索引中(如 select name, age, score from ...),即使右侧列失效,优化器仍会用 “索引全扫描”(无需回表),效率依然高于全表扫描。

联合索引中,什么时候索引是有效的,什么时候所以是无效的?

注意:是不是使用索引,和查询条件的顺序无关(优化器会自动调整条件的顺序),但和这些字段的查询手段有关

例子:建立了abc的联合索引,相当于建立了 a的单列索引,ab的联合索引,以及abc的联合索引

情况一:模糊查询生效失效的情况

一般根据最左匹配的原则,但在遇到范围查询后,匹配终止,也就是说,当条件为:

a like ‘%str%’ 或者 a like ‘%str’ 时,不走索引;

当条件为 a like ‘str%’ 或者 “>”, “<”, "between"时, 仅使用了联合索引中a的部分

b,c 同理,根据查询方式不同,即便条件中的3个字段都在索引里,也不一定使用了全索引

假如条件是 a = 1 and b = 2 and c = 3 这类情况,是必然走这个联合索引了

情况二:a% and b的情况

b不走索引但走索引下推(b走了索引下推,减少了回表次数。。。。。如果b没有索引下推,则还要在a%回表后进行一次b筛选)

B是不走索引的话:

首先A%会走索引的进行模糊查询,将模糊查询出来的主键进行回表(如果覆盖索引就不需要回表),回表后再根据B进行筛选,这时候B是不走索引的
B使用索引下推的话:

首先A%会走索引的进行模糊查询,模糊查询结束的时候,会将B条件索引下推到存储引擎层,这时候会从模糊查询的结果中筛选出来符合B的。最后再回表查询对应的字段(如果覆盖索引就不需要回表)。减少了回表的次数。

到此这篇关于MySQL的联合索引范围条件失效问题解决办法的文章就介绍到这了,更多相关MySQL联合索引范围条件失效内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文