MySQL之SQL分析三部曲实际案例(一)

附上MySQL之SQL分析三部曲地址http://blog.itpub.net/29510932/viewspace-1709732/

-------------------------------------------------------------------------------------------------正文---------------------------------------------------------------------------------------------------------------

由于是生产环境下进行的,截图和SQL都隐去了一些信息

背景:有用户在抱怨生产系统上,某一个Web的页面太慢,忍无可忍
问题分析过程:略
问题聚焦:最终确定是某一个SQL语句太慢,查询时间用了4s(慢查询日志给出的信息)
罪魁祸首的SQL语句:

点击(此处)折叠或打开

  1. select col1,col2......colN
  2. from tom
  3. inner join toa on tom.id = toa.id
  4. left join tov on tom.id = tov.id
  5. inner join toi on tom.id = toi.id
  6. left join fo on tom.stype = 2 and fo.id = tom.id
  7. WHERE ( tom.ostatus = 1 and tom.sid in ( 1 , 2 , 3) and tom.ptime >= '2333-01-01 09:41:58.056' and tom.ptime = '2333-02-01 09:41:58.056' and tom.otype != 2 and toi.iid = '233333333333333' and tom.stype in ( 1 , 2 ) ) order by tom.ptime desc limit 20,20

SQL分析三部曲之一:explain,结果如下图

可以很明显的看到主要问题出在tom表上,使用了索引还有这么高的rows,从常规考虑来说,这个SQL使用了错误的索引
那么查看一下这个表上的索引,发现tom表上是存在联合索引的,显然,手动指定索引就可以了。

以解决问题为目的,就到上面就可以了,不过为了弄清楚优化器没有选择使用这个联合索引,反而用了效率更低的其他的索引的原因,还需要看具体的优化器判断过程

SQL分析三部曲之二:profile,拖慢SQL的主要问题在于扫描了不必要的数据,因此不必用profile来寻找时间消耗的主要目标

SQL分析三部曲之三:optimizer_trace,操作过程略,部分结果如图

从下图可以看到,在判断where条件时,优化器选择了这个联合索引,同时计算出了rows和cost

接着往下看优化器的逻辑,在最后,由于SQL语句中有limit m,n的存在,优化器重新计算了使用这个索引的cost

接下来就是喜闻乐见的索引更换

选择另外一个索引是因为primary key和ptime的索引能够组成二级索引,而且ptime也出现在了where的条件当中,所以最终的结果,就变成了最前面explain的extra里面出现的Using index condition

在实际的测试和验证过程中,删掉limit语句以后,优化器就能正确的选择最优的索引,也证明了limit m,n这个语句是导致优化器做出了错误判断的罪魁祸首~

优化器计算的cost出现了问题?MySQL的优化器一直以来背了无数黑锅(口碑烂),不过真正导致优化器做出错误选择的家伙,一般是表的统计信息不完整/不全面/不正确........

最后附上正确的执行计划截图

rows已经降到了11~

PS:Using index condition,这是在在5.6之后新加入的特性,index condition pushdown,百度可以搜到很多介绍的文章,这里就略过了

时间: 2024-10-26 17:38:37

MySQL之SQL分析三部曲实际案例(一)的相关文章

MySQL之SQL分析三部曲实际案例(二)

附上MySQL之SQL分析三部曲地址http://blog.itpub.net/29510932/viewspace-1709732/ -------------------------------------------------------------------------------------------------正文-----------------------------------------------------------------------------------

MySQL之SQL分析三部曲实际案例(三)--limit的陷阱

附上MySQL之SQL分析三部曲地址http://blog.itpub.net/29510932/viewspace-1709732/ 姐妹篇http://blog.itpub.net/29510932/viewspace-1732876/ (其实是难兄难弟篇) -------------------------------------------------------------------------------------------------正文-------------------

MySQL之SQL分析三部曲实际案例(六)--file sort与key_len

-------------------------------------------------------------------------------------------------正文--------------------------------------------------------------------------------------------------------------- 问题发生于对即将上线的SQL进行review时,实际问题的截图隐去部分生产环境

MySQL之SQL分析三部曲实际案例(五)--临时表,优化器的选择

-------------------------------------------------------------------------------------------------正文---------------------------------------------------------------------------------------------------------------问题出现于生产环境,为了方便表述,在测试环境构造了类似的场景 所有操作都是基于M

MySQL之SQL分析三部曲

在倒腾DB的时候,SQL会占据非常大的一部分时间,遇到执行效率不高的SQL时,就需要想办法找到执行效率不高的原因,这里简单记录分析SQL的三个步骤~ 使用的数据库版本为MySQL-5.7.7-rc -----------------------------------------------------------------------------------------正文------------------------------------------------------------

MySQL SQL 分析 - 参数化查询 vs query cache 功能

query cache,  mysql 5 开始附带的一个功能, 与引擎无关, 只与数据查询语法相关.   测试描述: 当前使用中是 MySQL-5.6.14 Linux RHEL6  64 位系统产生环境,  使用 INNODB 引擎, 分配 innodb 2g 内存空间   [root@TiYanPlat ~]# uname -a Linux TiYanPlat 2.6.32-358.el6.x86_64 #1 SMP Tue Jan 29 11:47:41 EST 2013 x86_64

MySQL的日志分析工具

MySQL的性能从查看日志开始.硬件配置低常常导致这样的问题,但事实上大多数情况并不在这里.某些"慢"SQL阻塞了其他语句的执行,优化查询是第一步需要做的. "工欲善其事必先利其器",MySQL自身的一款mysqldumpslow 查询日志分析器,该工具不但陈旧,验证规范不准确.今天要说的是Percona 的工具pt-query-digest,它能够分析慢查询日志内容,生成查询报告,过滤,重放或传送一些查询语句至MySQL,PostgreSQL,memcached或

SQL Server并行死锁案例解析

原文:SQL Server并行死锁案例解析 并行执行作为提升查询响应时间,提高用户体验的一种有效手段被大家所熟知,感兴趣的朋友可以看我以前的博客SQL Server优化技巧之SQL Server中的"MapReduce", SQL Server优化器特性-位图过滤(Bitmap),然而正如我一直强调的,任何事物均有利弊,重点在于抉择.近日有朋友问我关于在今年7月份SQL Saturday中分享的并行执行中关于并行死锁的内容,这里我就详细解释下我举的实例中的并行死锁.      并行死锁

mysql 显示SQL语句执行时间的代码_Mysql

MySQL 的 SQL 語法調整主要都是使用 EXPLAIN , 但是這個並沒辦法知道詳細的 Ram(Memory)/CPU 等使用量. 於 MySQL 5.0.37 以上開始支援 MySQL Query Profiler, 可以查詢到此 SQL 會執行多少時間, 並看出 CPU/Memory 使用量, 執行過程中 System lock, Table lock 花多少時間等等. MySQL Query Profile 詳細介紹可見: Using the New MySQL Query Prof