MySQL:sending data状态包含了什么

一、问题由来

这是一个朋友问我的(@成都--麦涩可),原问题如下:

数据库发送数据给客户端这个时间算是sql的执行时间嘛?

要解决问题我们需要知道MySQL何时将数据传输给了客户端,既然是要传输实际的数据给客户端那么肯定是select语句了,同时我们要明白一个正常select运行到底要经历哪些阶段。

二、一个简单SELECT语句经历的阶段

2392  T@10: | | | | | THD::enter_stage: 'checking permissions' /root/mysql5.7.14/percona-server-5.7.14-7/sql/auth/sql_authorization.cc:843

2404  T@10: | | | | | | THD::enter_stage: 'Opening tables' /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_base.cc:5719

2512  T@10: | | | | | THD::enter_stage: 'init' /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_select.cc:121

2681  T@10: | | | | | | | THD::enter_stage: 'System lock' /root/mysql5.7.14/percona-server-5.7.14-7/sql/lock.cc:321

2772  T@10: | | | | | | | THD::enter_stage: 'optimizing' /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_optimizer.cc:151

2865  T@10: | | | | | | | THD::enter_stage: 'statistics' /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_optimizer.cc:386

3329  T@10: | | | | | | | THD::enter_stage: 'preparing' /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_optimizer.cc:494

3466  T@10: | | | | | | THD::enter_stage: 'executing' /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_executor.cc:119

3474  T@10: | | | | | | THD::enter_stage: 'Sending data' /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_executor.cc:195

3668  T@10: | | | | | THD::enter_stage: 'end' /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_select.cc:199

3685  T@10: | | | | THD::enter_stage: 'query end' /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_parse.cc:5174

3754  T@10: | | | | THD::enter_stage: 'closing tables' /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_parse.cc:5252

3882  T@10: | | | THD::enter_stage: 'freeing items' /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_parse.cc:5855

实际上整个阶段都算到了语句的实际消耗时间之中的,但是慢查询记录的是:

实际执行时间 = (freeing items 末端的时间) 实际消耗时间 - (System lock末端的时间 )比如MDL LOCK等待时间 - (Innodb层锁定的时间)行锁等待消耗时间

关于慢查询的详细情况可以参考我的一篇文章,这里不再重述。

三、什么是Sending data状态

实际上这个状态是select语句才会有的,如果是DML则不同但是都有等同的阶段如下:

select:Sending data

insert语句:Update

delete/update:Updating

这个阶段非常的巨大,它至少包含了:

Innodb 层数据的定位返回给MySQL 层

Innodb 层数据的查询返回给MySQL 层

Innodb 层数据的修改(如果是MDL)

Innodb 层加锁以及等待

等待进入Innodb层(innodb_thread_concurrency参数)

MySQL 层发送数据给客户端

可以看到基本所有和Innodb层打交道的过程都包裹在这个状态下面,当然我只是列举了我想到的一些,其实可能还有很多很多,这里我也把

MySQL 层发送数据给客户端

包含在 Sending data的答案给出了,下面我们进行分析。

四、如何证明Sending data状态包含了网络数据传输的时间

之前你可以参考一下我的文章

我们建立一个简单的表如下,并且填充数据如下:

Create Table: CREATE TABLE `ty` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `a` int(11) DEFAULT NULL,  `b` int(11) DEFAULT NULL,

PRIMARY KEY (`id`),

KEY `idxa` (`a`)

) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4

mysql> select * from ty;

+----+------+------+| id | a    | b    |+----+------+------+|  8 |    2 |    3 ||  9 |    5 |    4 || 10 |    6 |    7 || 11 |    6 |    8 |+----+------+------+4 rows in set (4.14 sec)

我们执行如下语句:

mysql> desc select * from ty where a =6 and b=8;

+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------------+| id | select_type | table | partitions | type | possible_keys | key  | key_len | ref   | rows | filtered | Extra       |

+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------------+

|  1 | SIMPLE      | ty    | NULL       | ref  | idxa          | idxa | 5       | const |    2 |    33.33 | Using where |+----+-------------+-------+------------+------+---------------+------+---------+-------+------+----------+-------------+

mysql> select * from ty where a =6 and b=8;

+----+------+------+| id | a    | b    |+----+------+------+| 11 |    6 |    8 |+----+------+------+1 row in set (7.22 sec)

注意:这里的语句执行时间很长是因为我打了GDB断点所以看起来很久而已

我做了语句的trace,这个语句大概需要如下步骤:

首先Innodb定位到索引

idxa

数据6所在位置这是初次定位调用函数ha_innobase::index_read,返回数据| 10 | 6 | 7 |给MySQL层,但是MySQL层过滤掉不符合条件 a =6 and b=8 不需要返回给客户端。

1547 T@12: | | | | | | | | >handler::ha_index_read_map   1548 T@12: | | | | | | | | | >index_read (这里进行初次访问索引定位)

1552 T@12: | | | | | | | | | | >row_search_mvcc

1553 T@12: | | | | | | | | | | | >btr_cur_search_to_nth_level   1554 T@12: | | | | | | | | | | |

...

1593 T@12: | | | | | | | | | |

1594 T@12: | | | | | | | | |

1595 T@12: | | | | | | | | <:ha_index_read_map>

1596 T@12: | | | | | | | | >evaluate_join_record (这里进入MySQL 层where条件判断流程,不满足不发送)

...   1600 T@12: | | | | | | | |

定位完成后再次访问索引

idxa

的下一条数据,Innodb直接读取就好了调用函数ha_innobase::index_next_same,返回数据| 11 | 6 | 8 |给Mysql层,因为满足条件 a =6 and b=8

所以返回给客户端

1601 T@12: | | | | | | | | >handler::ha_index_next_same(这里就是顺序访问索引的下一行数据了)   1602 T@12: | | | | | | | | | >general_fetch

1603 T@12: | | | | | | | | | | >row_search_mvcc

....

1607 T@12: | | | | | | | | | |

1608 T@12: | | | | | | | | |

1609 T@12: | | | | | | | | <:ha_index_next_same>

1610 T@12: | | | | | | | | >evaluate_join_record(这里进入MySQL 层where条件判断流程,满足条件需要发送)   1613 T@12: | | | | | | | | | >end_send

1614 T@12: | | | | | | | | | | >Query_result_send::send_data(这里就是发送数据给客户端了,也就是通过网络发送数据给客户端了)

1615 T@12: | | | | | | | | | | | >send_result_set_row   1616 T@12: | | | | | | | | | | |

1620 T@12: | | | | | | | | | | <:send_data>

1621 T@12: | | | | | | | | | | >Protocol_classic::end_row

1622 T@12: | | | | | | | | | | <:end_row>

1625 T@12: | | | | | | | | |

1626 T@12: | | | | | | | |

因为是非唯一索引因此需要再次访问下一条数据来判断已经读取了所有a=6的数据,因此Innodb需要在读取索引

idxa

的下一条数据调用函数ha_innobase::index_next_same。

1627 T@12: | | | | | | | | >handler::ha_index_next_same(这里就是顺序访问索引的下一行数据了)   1628 T@12: | | | | | | | | | >general_fetch

1629 T@12: | | | | | | | | | | >row_search_mvcc

...

1639 T@12: | | | | | | | | | |

1640 T@12: | | | | | | | | |

1641 T@12: | | | | | | | | <:ha_index_next_same>

所以总结整个流程一共经历了一次索引定位,两次索引顺序读取,一共读取了三条数据,但是返回给MySQL层的只有前面两条数据,通过MySQL层的过滤只发送给了客户端一条满足条件的数据。

五、总结

很显然数据返回给客户端的时间包含在了整个语句的实际消耗时间中,同时包含在了慢查询的实际执行时间(Query_time指标)中,它是在sending data状态下完成的。

作者微信:

mysql sending data_MySQL:sending data状态包含了什么相关推荐

  1. mysql load会锁表吗_Mysql必读MySQL中由load data语句引起死锁的解决案例

    <MysqL必读MysqL中由load data语句引起死锁的解决案例>要点: 本文介绍了MysqL必读MysqL中由load data语句引起死锁的解决案例,希望对您有用.如果有疑问,可 ...

  2. mysql的sererdata_MySQL_win2008 R2服务器下修改MySQL 5.5数据库data目录的方法,说明: 操作系统:Windows Server - phpStudy...

    win2008 R2服务器下修改MySQL 5.5数据库data目录的方法 说明: 操作系统:Windows Server 2008 R2 MySQL版本:5.5.25a MySQL程序安装目录:D: ...

  3. 【转贴】mysql导入数据load data infile用法

    mysql导入数据load data infile用法 基本语法: load data [low_priority] [local] infile 'file_name txt' [replace | ...

  4. 解决[ERROR] [MY-013276] [Server] Failed to set datadir to ‘F:\Mysql\mysql-8.0.19-winx64\data\‘ (OS er

    解决[ERROR] [MY-013276] [Server] Failed to set datadir to 'F:\Mysql\mysql-8.0.19-winx64\data' (OS errn ...

  5. mysql 启动报错Can't connect to local MySQL server through socket '/data/mysql/mysql/mysql.sock'(111)...

    1:首先mysql本地连接报错: Can't connect to local MySQL server through socket '/data/mysql/mysql/mysql.sock'(1 ...

  6. MySQL查询 json 字段中是否包含某个value

    MySQL查询 json 字段中是否包含某个value 方法一: 1.简单版本 :查询json的key SELECT * FROM 表名 where 字段名 -> '$.json中的key' = ...

  7. MySQL5.7执行mysqld命令出现Can‘t change dir to ‘C:\Program Files\MySQL\MySQL Server 5.7\data\‘错误

    执行mysqld -P3307 出现如下错误: mysqld: Can't change dir to 'C:\Program Files\MySQL\MySQL Server 5.7\data\' ...

  8. 【mysql安装问题】mysqld: Can‘t create directory ‘E: oft\mysql\mysql-5.7.19-winx64\data\‘ 两种解决办法

    安装完mysql之后,要初始化数据文件,输入 mysqld --initialize-insecure --user=mysql 然后可能会出现如下错误**: mysqld: Can't create ...

  9. MySQL5.7报错Can‘t change dir to ‘C:\Program Files\MySQL\MySQL Server 5.7\data\‘

    执行mysqld --initilize-insecure命令后报错页面如下: 解决办法: 根据报错提示去C:\Program Files\MySQL\MySQL Server 5.7\data\下创 ...

  10. mysql sending data状态

    select * from searchzh where modified_date > '2009-09-02 14:45:22'; 一条mysql查询语句的性能:sending data 耗 ...

最新文章

  1. 7.1 pdo 宝塔面板php_记宝塔面板中 PHP升级到 7.3.16安全版本概要
  2. 手机网页 右边的空白区
  3. java显式构造函数_C++中的显式构造函数
  4. a*算法的时间复杂度_数据结构(1)——算法和时间复杂度
  5. 【LeetCode笔记】剑指 Offer 15-. 二进制中1的个数 (Java、位运算)
  6. WakaTime 记录你的时间(Moana 自动同步信息客户端)
  7. 信息学奥赛一本通(1238:一元三次方程求解)
  8. CentOS 7 安装Docker
  9. IT中一些常见英汉互译
  10. 图像处理中各种边缘检测的微分算子简单比较(Sobel,Robert, Prewitt,Laplacian,Canny)
  11. Atitit mybatis的扩展使用sql udf,js java等语言 目录 1.1. 默认,mybatis使用xml,sql等语言来书写业务流程 1 2. 使用ognl调用java函数 1 3
  12. java xstream json_详解XML,Object,Json转换与Xstream的使用
  13. Poj 2187 旋转卡壳
  14. 批量 材质 调整_超实用的3dmax技巧,教你如何批量处理材质
  15. matlab 空间解析几何,Matlab 数学软件包在向量代数—空间解析几何中的应用
  16. 初创企业适用的邮件群发软件
  17. Improved autoencoder for unsupervised anomaly detection
  18. Ctfshow菜狗杯------传说之下(雾)
  19. 项目环境搭建,数据库,以及Swagger2介绍(二)
  20. SQL SERVER插入数据操作

热门文章

  1. 多项式计算的Horner 方法
  2. 霍纳法则c语言算法代码,霍纳法则(Horner Rule)介绍及C语言实现
  3. Linux设备驱动之udal341声卡驱动与madplay播放器移植
  4. c# webbrowser html5,C#设置WebBrowser IE浏览器版本
  5. centos格式化优盘命令_centos 格式化分区
  6. 撤销 git rebase
  7. 时间戳转换格林威治时间
  8. 我认为到现在写的最好的一本小说 《紫川》
  9. PureStake CEO Derek Yoo解释Moonbeam背后的技术
  10. OM302工业DTU对接亚控kingscada,实现水泵站一体化智慧改革