比想象中更复杂一点的MySQL Slow Query Log

1. 问题概述

在分析 Slow Query Log 时,记录下的SQL语句,明明会对一张表执行全表扫描,可为什么慢日志中的 Rows_sent 、Rows_examined 和表的真实记录数也是不一样,甚至相差N多倍。还有一个细节就是上述的SQL语句,执行多次,在慢日志中记录下多条记录,记录之间Rows_sent 、Rows_examined也差别明显。

这是什么原因导致的呢?

2.举例说明

假如,有一张 product_stock的表,其全表的数据量为80201010,size 约为56G。

对全表进行count(*),在慢日志留下的记录如下

```
# Time:2019-06-06T13:51:22.111111+08:00
# User@Host hehe[hehe] @ localhost [] Id: 868686
# Query_time : 39.112233 Lock_time: 0.000333 Rows_sent 1 Rows_examined: 80201010 
SET timestamp .....;
select count(*) from product_stock;
```

但是系统应用触发的慢SQL记录如下

```
# Time:2019-06-05T14:22:22.111222+08:00
# User@Host uwser[uwser] @ [XX.XX.XX.XX] Id: 667766
# Query_time : 520.662233 Lock_time: 0.000296 Rows_sent 820111 Rows_examined: 820111 
SET timestamp .....;
select * from product_stock where 1=1;
```

说明: where 1=1 ,是系统框架自动补全的,目的是防止SQL语句没有where 条件,这个是无碍的。

确信 整个语句就是全表扫描,问题是为什么它记录下来的扫描行数只是表数据的一小部分?也没有limit限制啊?

3.官方文档对慢日志的定义

The slow query log consists of SQL statements that take more than long_query_time seconds to execute and require at least min_examined_row_limit rows to be examined. The slow query log can be used to find queries that take a long time to execute and are therefore candidates for optimization.

The time to acquire the initial locks is not counted as execution time. mysqld writes a statement to the slow query log after it has been executed and after all locks have been released, so log order might differ from execution order.

• Query_time: duration

The statement execution time in seconds.

• Lock_time: duration

The time to acquire locks in seconds.

• Rows_sent: N

The number of rows sent to the client.

• Rows_examined:

The number of rows examined by the server layer (not counting any processing internal to storage engines).

这些知识对描述的疑惑没有直接帮助。还需我们继续探寻。

4. 猜想

慢日志记录的行数只是整个表的一部分,那会不会是还没执行完?会不会还在执行中被取消了?才导致只是scan其中的部分,返回的行数只是已scan的部分?

例如,如果条件允许的话,整个scan过程需要10分钟,但是执行到1分钟时,因为连接参数设置或则客户端主动取消,才进行了1/10,但是这个SQL语句还是被慢日志记录下来了,虽然它没有执行完整。

5.猜想验证

为了使验证过程简单直接,直接通过本地mysql客户端连接吧。

5.1 执行过程中,直接cancel

当然,cancel的时候,已执行的时间一定要大于自定义的慢查询时间阈值。

截取其中的一条慢日志

```
# Time:2019-06-06T18:36:18.554477+08:00
# User@Host uwser[uwser] @ [XX.XX.XX.XX] Id: 842366
# Query_time : 20.662233 Lock_time: 0.000296 Rows_sent 3691064 Rows_examined: 3691064 
SET timestamp .....;
select * from product_stock
```

cancal取消后,仍然会记录下慢日志,并且只返回已经扫描的数据(80201010中的3691064), 此种情况,验证了猜想是正确的。

5.2 执行中被Kill

当然,被Kill的时候(新打开一个connection去kill即可),已执行的时间一定要大于自定义的慢查询时间阈值。

```
# Time:2019-06-06T19:12:10.553322+08:00
# User@Host uwser[uwser] @ [XX.XX.XX.XX] Id: 842366
# Query_time : 50.662233 Lock_time: 0.000456 Rows_sent 10121006 Rows_examined: 10121006 
SET timestamp .....;
select * from product_stock
```

被KILL后,仍然会记录下慢日志,并且只返回已经扫描的数据(80201010中的10121006), 此种情况,验证了猜想是正确的。

6.结论

1) 被Cancel 或者 被KILL后,SQL语句如果符合慢日志时间,仍然会被记录下来,虽然它没有被完整下执行完;

2)此时的查询时间、扫描行数、返回行数,是截至到被Cancel 或者 被KILL时的 已执行时间、已Rows_sent 行数和 已Rows_examined行数;

3)Query_time、Rows_sent 行数、Rows_examined,可能不是SQL语句已完整执行的结果统计,只是整个SQL过程部分进度的统计,即截至到 被Cancel 或者 被KILL节点的统计;

4)上述情况发生时,执行多次,在慢日志中记录下多条记录,记录之间不同数据不同 是因为SQL受获取执行锁、DB执行时压力情况等因素的不同,导致退出时执行进度不同,各记录间 执行时间、 Rows_sent 、Rows_examined不同也是可以理解的。

文章整理自互联网,只做测试使用。发布者:Lomu,转转请注明出处:https://www.it1024doc.com/6315.html

(0)
LomuLomu
上一篇 2025 年 1 月 14 日 上午7:18
下一篇 2025 年 1 月 14 日 上午8:19

相关推荐

  • 蓝桥杯竞赛备战指南:核心知识点与实战题型解析(C++/Java/Python版)

    2025蓝桥杯竞赛备战全攻略 ——核心知识点精讲与典型题型剖析 一、命题规律解读 通过研究近三届赛事真题,我们发现试题主要聚焦于 算法基础、数据结构应用、数理逻辑、文本处理、编程语言特性 五大板块,并呈现出向 动态规划、图论算法、贪心策略 等高阶知识点倾斜的趋势。 1. 算法核心模块(重点考核) 排序与检索技术 分治排序(快排/归并) 折半查找(含变形题型)…

    未分类 2025 年 5 月 11 日
    53400
  • 【Java】异常处理见解,了解,进阶到熟练掌握

    各位读者,早安、午安、晚安! 如果您发现这篇文章对您有所启发,不妨点赞、评论、分享,您的支持是我不断进步的动力。也欢迎您将这篇文章推荐给更多人。 今天我们将深入探讨Java面向对象编程中的抽象类和接口,让我们一起来看看它们是如何协同工作的。 目录 1.(throws和throw)我们选择忽略这个异常,将其向外抛出 1.1:使用throws时的注意事项 1.2…

    2024 年 12 月 28 日
    42600
  • Java刷题常见的集合类,各种函数的使用以及常见的类型转化等等

    目录 前言 集合类 ArrayList 1. 创建和初始化 ArrayList 2.添加元素 add 3.获取元素 get 4.删除元素 remove 5.检查元素 6.遍历 ArrayList LinkedList Stack 1. 创建Stack对象 2. 压入元素 (push) 3. 弹出元素 (pop) 4. 查看栈顶元素 (peek) 5. 检查栈…

    2025 年 1 月 6 日
    49600
  • Java之反射

    目录 反射 定义 主要用途 反射相关的类 Class类中【获得类相关方法】 Class类中【获得类中属性相关的方法】 Class类中【获得类中注解相关的方法】 Class类中【获得类中构造器相关的方法】 Class类中【获得类中方法相关的方法】 获得Class对象 代码示例1 代码示例2 反射的优缺点 反射 定义 Java的反射(reflection)机制是在…

    2024 年 12 月 28 日
    46400
  • Python Cookbook(第3版)中文版-PDF免费下载

    Python Cookbook(第3版)中文版-PDF免费下载 适读人群 :Python程序开发人员、编程爱好者、在校大学生 电子版仅供预览,下载后24小时内务必删除,支持正版,喜欢的请购买正版书籍:https://item.jd.com/13897579.html Python图书升级版本,Python编程从入门到实践,涵盖Python3.3,包含大量实用…

    2024 年 12 月 30 日
    48200

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信