MYSQL索引失效整理一

在mysql5.7中,一般为了查询速度,通常会引入索引,但是有时候我们的索引并没有引起效果,所以整理下一般在什么情况下会引起索引失效,即索引没有被使用。

一.发生隐式类型转换

现在我们有一个名为t_test的数据表,他的字段与数据存储类型如下所示,并且在字段phone字段建立索引:

名称类型长度
idbigint0
namevarchar10
phonevarchar20
age

int

0
adreessvarchar50

 

 

 

 

 

 

 

我们查询phone字段为具体数值的查询,可以为:

select * from t_test where phone =13555455506

可以正常得到我们想要的结果,但是由于phone为varchar字符类型,而不是长整型,所以我们查看下这个sql的执行计划:

explain select * from t_test where phone =13555455506

并且可以得到以下计划:

idselect_typetablepartitionstypepossible_keyskeykey_lengthrefrowsfilteredExtra
1SIMPLEt_test ALLindex_phone   1100Using where

 

 

 

我们可以通过上述列表看到possible_keys为执行时预计可能用到的索引为phone上的索引,key为实际用到的索引为空,则表示实际查询不会用到索引,则是因为MySQL会将我们传入的参数隐式转换为数据表中存储的类型,索引时根据Btree的有序性进行遍历的,但是转换之后的参数破环了有序性的规则。

所以我们要将传入参数加上引号,以表示此参数为字符串类型,如下:

select * from t_test where phone ='13555455506'

二.表达式计算

还是使用上面的表,我们在age字段上加入索引,现在我们有一个查询,要求查询年龄age在两年前为18的数据,则查询语句如下:

select * from t_test where age -2=18

可以正常得到我们想要的结果,但是由于我们在age查询的时候给他赋予了表达式,所以我们查看下这个sql的执行计划:

explain select * from t_test where age -2=18

并且可以得到以下计划:

idselect_typetablepartitionstypepossible_keyskeykey_lengthrefrowsfilteredExtra
1SIMPLEt_test ALL    1100Using where

 

 

 

我们可以清楚看到,索引并没有使用,那么我们应该如何修改以达到要求呢,我们只需要把计算挪到等号右侧即可:

 select * from t_test where age =18+2

原因与第一个类似。数据库在计算时无法保证与索引树一致,只好不用索引。

三.使用函数

现在我们有这样一个查询,查询出手机号码前三位为158的数据,则查询语句如下:

select * from t_test where LEFT(phone,3)='158'

可以正常得到我们想要的结果,但是由于我们使用了函数,所以我们查看下这个sql的执行计划,语句省略,直接看结果:

idselect_typetablepartitionstypepossible_keyskeykey_lengthrefrowsfilteredExtra
1SIMPLEt_test ALL    1100

Using where 

 

 

 

我们可以修改为如下语句:

select * from t_test where phone like '158%'

原因同上面两个类似,这正是用到了我们msyql的索引最左原则进行匹配。

四.左或者左右模糊匹配

现在我们有这样一个查询,查询出地址包含天安门的数据,则查询语句如下:

select  *  from t_test where adreess like '%天安门%'

可以正常得到我们想要的结果,但是由于我们使用了左右模糊匹配,则可以查看sql的执行计划如下,查看结果:

idselect_typetablepartitionstypepossible_keyskeykey_lengthrefrowsfilteredExtra
1SIMPLEt_test ALL    1100

Using where 

 

 

 

这里面也是由于不符合最左前缀匹配原则。如果我们只查询主键id与该索引字段,仍可使用索引,查询如下:

select  id,adreess  from t_test where adreess like '%天安门%'

由于不符合最左前缀,即使使用索引树,查询只能跟随Btree数依次遍历。

五.联合索引

联合索引我们要依据最左前缀原则,即最左字段,最左数据

如果我们删除age与phone上的单列索引,新增(age,phone)联合索引,则有以下规律

select * from t_test where age =20 //使用了该联合索引

select * from t_test where phone like '131%' //没有使用该联合索引

select * from t_test where age =20 and  phone like '131%'//使用了该联合索引

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值