首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 「Sending data」狀態導致查詢極慢?定位思路與大字段優化實戰

     編輯:MySQL 資料庫相關知識

現象:幾萬行數據查 4-5 分鐘

Sphinx 從 MySQL 拉取源數據建索引,記錄數僅幾萬,但查詢耗時 4-5 分鐘。EXPLAIN 顯示索引用得不錯,無全表掃描。

定位三部曲

1. SHOW PROCESSLIST 看狀態

mysql> SHOW PROCESSLIST;
+----+------+-----------+------+---------+------+--------------+------------------+
| Id | User | Host      | db   | Command | Time | State        | Info             |
+----+------+-----------+------+---------+------+--------------+------------------+
| 12 | sphinx | 10.x.x.x | db   | Query   | 216  | Sending data | SELECT ...       |
+----+------+-----------+------+---------+------+--------------+------------------+

長時間停留在 Sending data。

2. 理解 Sending data 真實含義

非單純「發送數據」,而是「收集數據 + 發送數據」。
當查詢使用索引定位行後,若 SELECT 列包含**非索引列**,MySQL 需回表(回主鍵聚簇索引)逐行讀取完整行數據,再組裝發送。大量隨機 IO 在此發生。

3. SHOW PROFILE 量化耗時分布

SET profiling=1;
-- 執行慢查詢
SHOW PROFILES;  -- 獲取 Query_ID
SHOW PROFILE FOR QUERY 1;
+----------------------+----------+
| Status               | Duration |
+----------------------+----------+
| Sending data         | 216.0000 |  -- 核心瓶頸
| ...                  | ...      |
+----------------------+----------+

對比實驗:定位罪魁禍首欄位

逐個排除 SELECT 列,發現 description VARCHAR(8000) 是元兇:

  • 不查 description:15 秒
  • 查 description:216 秒(15 倍差距)

原理深度解析:InnoDB 溢出頁機制

  • ROW_FORMAT=COMPACT/REDUNDANT 時,列長度 > 768 字節,前 768 字節存主頁,**餘下存溢出頁**
  • SHOW TABLE STATUS 顯示 Avg_row_length ≈ 1.5KB,頁大小 16KB → 每頁約 8 行,**大量行觸發溢出頁**
  • 回表時:順序讀主頁 → **隨機讀溢出頁** → 性能崩塌
  • 實測發現:**Buffer Pool 不緩存溢出頁**(邏輯合理:大對象不應污染熱點緩存)

解決方案對比

方案實施成本效果適用場景
查詢去掉大字段低(改應用 SQL)立竿見影業務允許不返回大字段
垂直拆表:大字段移獨立表中(改表結構+應用)徹底解決業務仍需大字段,但查詢頻率低
ROW_FORMAT=DYNAMIC/COMPRESSED低(ALTER TABLE)部分緩解MySQL 5.7+,配合 innodb_file_per_table
覆蓋索引包含大字段高(索引巨大)理論最快極少見,不推薦

最佳實踐建議

  1. 業務查詢默認不 SELECT *,顯式列出所需欄位
  2. 大文本/Blob 必須垂直拆表,主表只存核心屬性
  3. 表創建時指定 ROW_FORMAT=DYNAMIC(5.7+ 默認)
  4. 監控慢查詢中的 Sending data 佔比,超過 50% 即啟動大字段排查

總結

「Sending data 慢 = 大量回表讀非索引列 + 可能涉及溢出頁隨機 IO」。**垂直拆表隔離大字段** 是治本之策;**業務端禁 SELECT *、按需查詢** 是防患未然的鐵律。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved