专注收集记录技术开发学习笔记、技术难点、解决方案
网站信息搜索 >> 请输入关键词:
您当前的位置: 首页 > MySQL

MySQL查询有关问题排查-索引应用

发布时间:2010-05-20 14:01:29 文章来源:www.iduyao.cn 采编人员:星星草
MySQL查询问题排查-索引应用

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

本文地址:http://flyer0126.iteye.com/blog/2410145

 

    最近开发中需查询系统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

 

    索引如下:
 

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

explain select * from apps limit 1;


 

explain select id from apps limit 1;


 

     由此可见,第一条没有用到索引,按主键排序取到了第一条;第二条用到了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 ...

     不同表引擎索引的实现:


     至此,以上问题有了定论

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;


     至此,验证了索引覆盖问题(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.
     主要就是:假如索引覆盖覆盖了所选取的字段,会优先使用索引覆盖,因为效率更快。
     既然主键索引列包含所有数据列,那么主键索引列一样可以做到索引覆盖,那么优化器为什么不选择使用主键索引呢?

     在5.1.46中优化器在对index选择上做了一点改动: 

“Performance: While looking for the shortest index for a covering index scan, the optimizer did not consider the full row length for a clustered primary key, as in InnoDB. Secondary covering indexes will now be preferred, making full table scans less likely。”
     该版本中增加了find_shortest_key(),该函数的作用可以认为是选择最小key length的索引来满足我们的查询。

     mysqlfind_shortest_key()函数注释如下:

“As far as clustered primary key entry data set is a set of all record fields (key fields and not key fields) and secondary index entry data is a union of its key fields and primary key fields (at least InnoDB and its derivatives don’t duplicate primary key fields there, even if the primary and the secondary keys have a common subset of key fields), then secondary index entry data is always a subset of primary key entry. Unfortunately, key_info[nr].key_length doesn’t show the length of key/pointer pair but a sum of key field lengths only, thus we can’t estimate index IO volume comparing only this key_length value of secondary keys and clustered PK. So, try secondary keys first, and choose PK only if there are no usable secondary covering keys or found best secondary key include all table fields (i.e. same as PK):”

     总结:因为辅助索引总是主键的子集,从节约IO的角度,优先选择辅助索引。

     附:由于MySQL数据是通过文件形式进行存储的,那IO主要是指对数据文件的读写。

 

     至此,问题完结。

友情提示:
信息收集于互联网,如果您发现错误或造成侵权,请及时通知本站更正或删除,具体联系方式见页面底部联系我们,谢谢。

其他相似内容:

  • mysql服务正在启动或终止中请稍后片刻再试一次

    mysql服务正在启动或停止中请稍后片刻再试一次 启动mysql服务总是服务正在启动或停止中请稍后片刻再试一次 的提示怎么办? ...

  • mysql目录以及优化

    mysql索引以及优化 今天看到别人写的一些关于mysql索引的文章,有一些小收获,就以此开启我的随笔记录简单摘了一些重点 转载文章:http...

  • MYSQL查询今日、昨天、7天前、30天、本月数据

    MYSQL查询今天、昨天、7天前、30天、本月数据 今天: SELECT * FROM 表名 WHERE TO_DAYS( 时间字段名) = TO_DAYS(NOW()); 昨天: SEL...

  • MySQL的预加工技术

    MySQL的预处理技术 所谓的预处理技术,最初也是由MySQL提出的一种减轻服务器压力的一种技术! 传统mysql处理流程 1, 在客户端准备sql...

  • 怎么修改Xampp服务器上的mysql密码

    如何修改Xampp服务器上的mysql密码 今天自己在搞php的过程中发现,如果我们使用Xampp服务器自带数据库mysql,就必须先修改mysql的密...

  • MySQL安插emoji手机表情报错解决方案

    MySQL插入emoji手机表情报错解决方案 报错原因: 插入手机表情报错,类似 ...

  • 腾讯云装Mysql总结

    腾讯云装Mysql小结   这几天搞腾讯云服务器装mysql搞蒙了,本来还想这周就上线网站,看来不一定能行了。   总结一下吧   开...

  • MySql概念(2)

    MySql概念(二) 一、Sql规范?   sql是Structured Query Language(结构化查询语言)的缩写。SQL是专为数据库而建立的操作命令集,是一...

  • mysql主从复制原理引见

    mysql主从复制原理介绍 mysql主从复制原理 1)在mysql主库上,将改变记录到二进制日志(binary log)中。 2)在mysql从库上,IO线程将mys...

  • 如何查看和修改 MySQL 的最大连接数

    怎么查看和修改 MySQL 的最大连接数 通常,mysql的最大连接数默认是100, 最大可以达到16384。 1、查看最大连接数: show varia...

热门推荐: