mysql rows examined_MySQL源码学习:关于慢查询日志中的Rows_examined=0

在说明这个问题之前,我们先指出两个相关背景:1、MySQL的临时表,都是MyISAM的。2、MyISAM表中的记录总数是额外存储的,count(*)

最近在一个项目中DBA同学问了一个问题:为什么很多慢查询日志中显示 Rows_examined : 0?

需要说明的是, 这类慢查询语句都是类似 select count(*) from (…)t;

在说明这个问题之前,我们先指出两个相关背景:

1、MySQL的临时表,都是MyISAM的。

2、MyISAM表中的记录总数是额外存储的,count(*)的时候不需要遍历数据。

3、把count(*)转换为取一个const值这件事情,是在优化(optimize)阶段作的。

问题分析:

这个值对应于代码中的examined_row_count,用于统计每次执行过程中实际扫描的记录数。

正常的流程:

查询执行过程中,每个子查询的信息都在curr_join,其中curr_join->examined_rows在每次扫一行的时候++.子查询完成后,curr_join->examined_rows累积到examined_row_count中。

哪里清0的?

我们上面这个语句,from内的子查询,curr_join->examined_rows是正常的,但在外部计算count的时候,上面提到的优化结果认为这个阶段是不需要扫描表的,把thd->examined_row_count给置0了。罪魁代码在JOIN::exec()中。

从代码中的注释来看,似乎是一个没有考虑细致的地方,待求证。

1c58dca997074ea75a98642a19786922.png

改进分析:

纵然有很多理由,在慢查询日志中显示的0还是不友好的,可以理解为是一个bug。

实际上从上面的分析可知,如果是复合查询中的一个环节,尤其不是第一个环节,此处清0会使显示结果出错。从当前的thd信息中可以判断出是否使用了子查询,简单一点的修改,,根据thd.derived_tables信息来确定是否清0。

实际上每次执行开始之前的这个值是被reset过的,有理由怀疑这个地方实际上可以直接删除这句话。这个比较激进,要求证一下。

简单验证:

加了thd.derived_tables判断后,

14eb38accbe2463b931b9656716f18f9.png

方便调试起见,把所有的查询都打到slow_log了。

logo.gif

f68f2add0b68e4f9810432fce46917b7.png

本文原创发布php中文网,转载请注明出处,感谢您的尊重!

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值