久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

MySQL中sending data狀態包含了什么

135次閱讀
沒有評論

共計 6137 個字符,預計需要花費 16 分鐘才能閱讀完成。

這篇文章主要介紹“MySQL 中 sending data 狀態包含了什么”,在日常操作中,相信很多人在 MySQL 中 sending data 狀態包含了什么問題上存在疑惑,丸趣 TV 小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”MySQL 中 sending data 狀態包含了什么”的疑惑有所幫助!接下來,請跟著丸趣 TV 小編一起來學習吧!

一、問題由來

原問題如下:

數據庫發送數據給客戶端這個時間算是 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 狀態包含了網絡數據傳輸的時間

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

https://www.jianshu.com/p/25fed8f1f05e
 MySQL:Innodb Handler_read_* 變量解釋

我們建立一個簡單的表如下,并且填充數據如下:

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: | | | | | | | | | | |  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 狀態包含了什么”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注丸趣 TV 網站,丸趣 TV 小編會繼續努力為大家帶來更多實用的文章!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-07-24發表,共計6137字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 寿光市| 阜平县| 康定县| 屯门区| 龙口市| 襄樊市| 台北县| 平塘县| 延津县| 巴林左旗| 台江县| 上蔡县| 阜平县| 濉溪县| 皋兰县| 伊春市| 德兴市| 景泰县| 铜陵市| 漳浦县| 万宁市| 红河县| 新和县| 宁蒗| 邢台市| 沈阳市| 如皋市| 淮南市| 翼城县| 离岛区| 油尖旺区| 泾川县| 渑池县| 云梦县| 沁源县| 弥渡县| 遂川县| 仁布县| 铜鼓县| 绿春县| 抚松县|