`

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主要是指对数据文件的读写。

 

     至此,问题完结。

  • 大小: 49.6 KB
  • 大小: 35.2 KB
  • 大小: 42 KB
  • 大小: 231.3 KB
  • 大小: 35.3 KB
分享到:
评论

相关推荐

    mysql-connector-java-8.0.11.jar文件

    - **更好的错误处理**:提供了更详细的错误信息,便于排查问题。 总的来说,`mysql-connector-java-8.0.11.jar`是开发Java应用与MySQL数据库交互不可或缺的组件,它的正确使用能够帮助开发者高效地完成数据操作任务...

    mysql-gui-tools-noinstall-5.0-r17-win32.rar

    这使得用户能够轻松地将现有的应用程序和数据迁移到MySQL平台。 4. **MySQL Administrator**: MySQL管理员工具提供了一组高级的数据库管理和维护功能。它可以用于创建和管理数据库用户,监控服务器性能,进行备份...

    mysql-8.0.23-winx64-debug-test.zip

    总的来说,"mysql-8.0.23-winx64-debug-test.zip"是一个全面的MySQL开发和测试环境,涵盖了从数据库设置到故障排查的所有环节,对于开发和维护MySQL应用程序的人员来说,这是一个宝贵的资源。通过深入理解和熟练运用...

    mysql--linux--5.6

    同时,审计插件允许记录数据库操作,有助于监控和排查问题。 在备份与恢复方面,MySQL 5.6提供了更好的备份工具,如xtrabackup,支持在线热备份,能在不中断服务的情况下进行数据备份。此外,恢复过程也更加高效,...

    mysql-5.7.37-linux-glibc2.12-x86_64.tar.gz

    MySQL有错误日志、查询日志、慢查询日志等,通过配置`my.cnf`可以启用并调整日志设置,用于故障排查和性能分析。 9. **复制与高可用性**: MySQL支持主从复制,通过复制可以实现数据冗余和故障切换,提高系统的...

    mysql-8.0.29-winx64-debug-test.zip

    在Windows x64环境下,MySQL提供了调试和测试版本,这通常是为了开发人员和系统管理员进行深入的问题排查和性能优化。"mysql-8.0.29-winx64-debug-test.zip" 文件包含了在Windows 64位操作系统上运行的MySQL 8.0.29...

    mysql-5.7.35-winx64.rar

    - **日志管理**:配置错误日志、慢查询日志,便于排查问题和优化查询。 在MySQL 5.7.35中,还引入了如GTID(全局事务标识符)这样的特性,用于实现无冲突的数据复制,增强了InnoDB Cluster的高可用性。此外,SQL...

    mysql-5.7.20-win32-debug-test.zip

    MySQL是世界上最受欢迎的开源关系型数据库管理系统之一,其5.7.20版本是一个重要的里程碑,为...通过深入理解和有效利用这些工具,开发者可以确保其应用程序与MySQL数据库的无缝集成,并对可能出现的问题进行有效排查。

    mysql-8.0.4-rc-winx64.zip

    在使用MySQL时,了解SQL语言基础至关重要,包括创建数据库、表、索引,插入、更新和删除数据,以及执行查询。同时,理解如何备份和恢复数据,以及如何处理性能优化和故障排查也是每个MySQL管理员必须掌握的技能。 ...

    mysql-5.5.18-win32安装包及教程

    6. 日志系统:了解错误日志、慢查询日志和二进制日志的用途,以优化数据库性能和排查问题。 7. 性能优化:熟悉查询优化器的工作原理,使用`EXPLAIN`来分析查询执行计划,优化SQL语句。 8. 监控与性能监控:利用`...

    mysql-5.5.62-winx64.zip

    MySQL是世界上最受欢迎的开源数据库系统之一,特别是在Web应用程序中。MySQL 5.5版本是一个重要的里程碑,它在功能、性能和稳定性方面都有显著提升。在这个“mysql-5.5.62-winx64.zip”压缩包中,我们找到了MySQL ...

    mysql-8.0.26-macos11-x86_64.dmg

    - **JSON支持**:增强了对JSON数据类型的处理能力,包括JSON字段索引、查询和更新。 - **行级锁定**:在InnoDB存储引擎中提供更细粒度的锁定,提高并发性能。 - **加密存储**:支持加密表空间,确保数据安全性。 ...

    mysql-server-mysql-8.0.30.tar.gz

    - 错误日志记录了服务器的运行情况,帮助排查问题。 - binlog(二进制日志)用于复制和恢复,记录了所有更改数据库的事务。 9. **性能监控**: - MySQL 8.0提供了性能 Schema,一个内置的数据库,用于收集和分析...

    MySQL 1z0-883 题库demo

    9. **故障排查与日志分析**:学习如何解读错误日志,使用慢查询日志进行性能问题定位,以及如何使用General Query Log进行审计。 10. **云环境下的MySQL**:了解如何在云平台上部署和管理MySQL,包括Amazon RDS和...

    mysql-wins-32-64

    - 错误日志:MySQL会记录运行中的错误和警告,通过分析日志可以排查问题。 - 性能监视:利用Performance Schema或第三方工具,监控数据库性能指标,及时发现和解决问题。 9. **扩展功能**: - 插件支持:MySQL...

    mysql源码(mysql-8.2.0.tar.gz)

    在这个版本中,开发者和研究者可以深入理解MySQL的内部工作原理,进行定制化开发或者排查问题。MySQL 8.2.0的源码分析将涉及多个关键知识点: 1. SQL解析与执行:MySQL的核心在于其SQL解析器,它将用户输入的SQL...

    MySQL手册-5.5-en

    11. **日志与性能监控**:MySQL的日志系统(如二进制日志、错误日志)和性能监控工具(如慢查询日志、性能 Schema)对于排查问题和优化性能非常重要。 12. **MySQL服务器的管理**:包括服务器启动、停止、配置文件...

    MySQL数据库疑难杂症排查.pptx

    但是,在实际应用中,我们经常会遇到各种问题,例如数据库打开速度慢、查询效率低、服务器负载高等问题。因此,本文将对 MySQL 数据库的常见问题进行排查和解决。 一、确认问题的来源 在解决问题之前,我们需要...

    Lukaszewski -- MySQL for Python -- 2010.pdf

    - **性能优化**:提供了关于提高Python与MySQL集成后系统整体性能的建议,如索引优化、查询优化等。 - **安全措施**:强调了安全编程的重要性,并列举了一些常见的安全漏洞及其防范方法。 - **故障排查**:针对可能...

    mysql-8.0.20-linux-glibc2.12-x86_64.tar.gz

    MySQL 8.0.20的性能提升可能源于新的索引策略、查询缓存优化、InnoDB存储引擎的改进等。可以通过调整查询缓存大小、启用InnoDB缓冲池、使用覆盖索引、合理设计数据库表结构等方式进一步优化性能。 8. **备份与恢复...

Global site tag (gtag.js) - Google Analytics