MySQL中sending data状态含义了什么
发布时间:2021-12-21 17:37:09 所属栏目:MySql教程 来源:互联网
导读:这篇文章主要介绍MySQL中sending data状态包含了什么,在日常操作中,相信很多人在MySQL中sending data状态包含了什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答MySQL中sending data状态包含了什么的疑惑有所帮助!接
这篇文章主要介绍“MySQL中sending data状态包含了什么”,在日常操作中,相信很多人在MySQL中sending data状态包含了什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”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层锁定的时间)行锁等待消耗时间 关于慢查询的详细情况可以参考我的一篇文章,这里不再重述。 https://www.jianshu.com/p/1ffadf29d6c0 MySQL慢查询记录原理和内容解析 三、什么是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状态包含了网络数据传输的时间 之前你可以参考一下我的文章 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: | | | | | | | | | | | <btr_cur_search_to_nth_level 2009 ... 1593 T@12: | | | | | | | | | | <row_search_mvcc 6070 1594 T@12: | | | | | | | | | <index_read 9179 1595 T@12: | | | | | | | | <handler::ha_index_read_map 3190 1596 T@12: | | | | | | | | >evaluate_join_record (这里进入MySQL 层where条件判断流程,不满足不发送) ... 1600 T@12: | | | | | | | | <evaluate_join_record 1701 定位完成后再次访问索引 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: | | | | | | | | | | <row_search_mvcc 6070 1608 T@12: | | | | | | | | | <general_fetch 9487 1609 T@12: | | | | | | | | <handler::ha_index_next_same 3414 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: | | | | | | | | | | | <send_result_set_row 4967 1620 T@12: | | | | | | | | | | <Query_result_send::send_data 2915 1621 T@12: | | | | | | | | | | >Protocol_classic::end_row 1622 T@12: | | | | | | | | | | <Protocol_classic::end_row 1198 1625 T@12: | | | | | | | | | <end_send 2991 1626 T@12: | | | | | | | | <evaluate_join_record 1701 因为是非唯一索引因此需要再次访问下一条数据来判断已经读取了所有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: | | | | | | | | | | <row_search_mvcc 6070 1640 T@12: | | | | | | | | | <general_fetch 9487 1641 T@12: | | | | | | | | <handler::ha_index_next_same 3414 所以总结整个流程一共经历了一次索引定位,两次索引顺序读取,一共读取了三条数据,但是返回给MySQL层的只有前面两条数据,通过MySQL层的过滤只发送给了客户端一条满足条件的数据。 到此,关于“MySQL中sending data状态包含了什么”的学习就结束了,希望能够解决大家的疑惑。 (编辑:丽水站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |