Heim > Datenbank > MySQL-Tutorial > MySQL源码学习:关于慢查询日志中的Rows_examined=0

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

WBOY
Freigeben: 2016-06-07 17:02:26
Original
1159 Leute haben es durchsucht

在说明这个问题之前,我们先指出两个相关背景: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()中。

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

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

改进分析:

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

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

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

简单验证:

加了thd.derived_tables判断后,

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

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

linux

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage