MySQL查询排查方法_MySQL查询问题排查-索引应用

PS:原创文章,如需转载,请注明出处,谢谢!

最近开发中需查询系统id,随手写了两条sql,发现查询结构不同。

select * from apps limit 1;

id

city_code

short_name

company_code

1

410100

zz

ZZXJ8888

select id from apps limit 1;

id

2

最终发现,两次查询结果竟然不一致!

为了一探究竟,查阅一下表数据及相关索引如下:

id

city_code

short_name

company_code

1

410100

zz

ZZXJ8888

2

410100

zz

HNFG6666

索引如下:

46319eec596b1490c29bfe4069eae86d.png

那来看看MySQL本身是如何解释的:

explain select * from apps limit 1;

ffe678ff6cc05b09c5128f0a28faa143.png

explain select id from apps limit 1;

d60f11424271816994ddf2d1095f7fce.png

由此可见,第一条没有用到索引,按主键排序取到了第一条;第二条用到了uniq_company_code索引,按索引排序,取到了第二条。

总结一下:根据select的字段不同,MySQL选取的策略不同,导致查询结果不同。

但是存在几个疑问点

1、为什么语句2中并没有出现company_code字段,却会使用其索引(uniq_company_code)?

2、为什么语句1中就不会使用uniq_company_code索引?

回答以上问题之前,先了解一下MySQL常用表引擎索引的实现方式

示例表如下:

id

company_code

city_code

...

10

ZZXJ8888

410100

...

21

HNFD6666

410100

...

32

WH9999

420100

...

43

CS9999

430100

...

不同表引擎索引的实现:

9d22537f3900e262b9696a7d49e0fd43.png

至此,以上问题有了定论

1、因为uniq_company_code索引中包含id字段,语句2可以从uniq_company_code索引中直接取得数据,所以优化器选择走uniq_company_code索引;

2、而语句1中select * 选取了在uniq_company_code索引中不包含的列,所以无法使用uniq_company_code这个索引。

为了验证上面的结论,进一步实验:

explain select id, company_name from apps limit 1;

595c71314447725dbb6d26e144d67745.png

至此,验证了索引覆盖问题(company_name不在uniq_company_code索引覆盖范围内,无法使用其索引)。

那么,为什么要使用索引覆盖呢?MySQL是如下这么解释的。

It is possible that key will name an index that is not present in the possible_keys value. This can happen if none of the possible_keys indexes are suitable for looking up rows, but all the columns selected by the query are columns of some other index. That is, the named index covers the selected columns, so although it is not used to determine which rows to retrieve, an index scan is more efficient than a data row scan.      主要就是:假如索引覆盖覆盖了所选取的字段,会优先使用索引覆盖,因为效率更快。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值