比想象中更复杂一点的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/6665.html

(0)
LomuLomu
上一篇 2025 年 1 月 16 日 上午3:56
下一篇 2025 年 1 月 16 日 上午4:58

相关推荐

  • Java Bean的核心概念与应用解析

    Java Bean是遵循特定编码标准的Java类,其核心作用在于数据封装,并体现约定优先于配置的设计理念。它在企业级开发(如Spring生态)和图形界面开发(如传统Swing组件)中具有重要地位,是Java编程中广泛采用的基础模式。 Java Bean的核心特性 默认构造方法不可少 反射机制(例如Spring框架初始化对象)依赖无参构造器完成实例化 若存在带…

    未分类 2025 年 5 月 18 日
    34900
  • 小程序xcxCode逆向分析

    数据采集与xcxCode解密分析 一、声明 本文旨在提供学术交流,不应用于其他任何场合。文章中不包含完整代码,所有涉及的数据包内容、敏感网址和数据接口均已进行脱敏处理,严禁用于商业或非法活动,由此引起的后果与作者无关。未经授权,禁止转载或修改后传播本文,作者不承担因使用本文技术导致的任何后果。本文为原创,作者署名为小白,敬请尊重。 二、工具介绍 mitmpr…

    2024 年 12 月 26 日
    61800
  • A5433 Java+Jsp+Servlet+MySQL+微信小程序+LW+在线点餐小程序的设计与实现 源码 配置 文档

    在线点餐小程序的设计与实现 1.摘要 2.开发目的和意义 2.1 系统开发目的 2.2 系统开发意义 3.系统功能设计 4.系统界面截图 5.源码获取 1.摘要 摘 要近几年,人们生活水平日益提升,但工作强度和压力不断增强,尤其是对于上班族而言,到餐厅吃饭费时费力,而传统的APP点餐难以适应针对性,基于此,借助Web开发技术以及后台数据库,设计了在线点餐小程…

    2025 年 1 月 11 日
    48700
  • 2025年MacBook苹果电脑多版本JDK安装与环境配置指南:从JDK8到JDK22的完整教程

    本指南最后更新于:2024年11月28日,包含最新版本支持。重要更新记录:- 2024年02月:新增JDK17环境配置- 2024年05月:解决Maven与JDK版本切换冲突问题- 2024年06月:针对M系列芯片用户推荐ARM版本- 2024年08月:新增JDK22支持- 2024年11月:优化内容排版与视觉效果 本教程所有操作步骤均经过实际验证,确保可行…

    2025 年 5 月 19 日
    1.6K00
  • JDK、IDEA安装教程 IDEA安装2023年10月 最新最详细!免费、亲测成功!!!

    系列文章目录(Intellij IDEA2023年10月 最新教程) Java学习之IDEA的安装教程和使用 以下是第一章的内容:IntelliJ IDEA安装教程 文章目录 前言 准备工作 步骤(敲详细!!!) 前言 IDEA的安装是Java课程的入门,本人台式机于2023年7月份进行了系统重装,恰巧最近需要重新安装IDEA进行使用,借此机会给同学们分享我…

    未分类 2025 年 5 月 13 日
    40500

发表回复

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

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

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

关注微信