Mysql
在分析 mysql 查詢時沒有“複製到 tmp 表”狀態
我有一張有 100k 行的表
創建表`small_table`( `pk` int(11) NOT NULL AUTO_INCREMENT, `varc` varchar(255) 預設為空, `txt` 文本, 主鍵(`pk`) ) 引擎=InnoDB AUTO_INCREMENT=103925 預設字元集=utf8
我已經執行了以下查詢
select varc,count(*) from small_table group by varc;
我也做了同樣的介紹
+----------------------+----------+ | 狀態 | 持續時間 | +----------------------+----------+ | 出發| 0.000060 | | 檢查權限 | 0.000010 | | 開桌 | 0.004685 | | 初始化 | 0.000025 | | 系統鎖 | 0.000006 | | 優化 | 0.000002 | | 統計 | 0.000010 | | 準備| 0.000006 | | 創建 tmp 表 | 0.000020 | | 排序結果 | 0.000003 | | 執行 | 0.000005 | | 發送數據 | 0.001720 | | 創建排序索引 | 0.000033 | | 結束 | 0.000002 | | 查詢結束 | 0.000004 | | 刪除 tmp 表 | 0.000004 | | 查詢結束 | 0.000002 | | 關閉表| 0.000004 | | 釋放物品 | 0.000015 | | 清理| 0.000007 | +----------------------+----------+
該配置文件具有創建 tmp 表狀態(通過 mysql 文件,這意味著在記憶體或磁碟中創建了一個 tmp 表)。我懷疑配置文件沒有復製到 tmp 表狀態(在狀態期間,伺服器將復製到記憶體中的臨時表。)我的假設是它已經創建了一個 tmp 表並且沒有使用它。我對嗎?
我的複製到 tmp 表狀態在哪裡?
它只是有一個稍微不同的名字。它是“創建 tmp 表”,這也更有意義。MySQL 知道將需要一個臨時表,因此它會即時生成它。狀態名稱“複製到 tmp 表”選擇不當。
我通常發現 Profile 沒用。通常“發送數據”是最上面的條目。這沒有給出應該修復什麼以提高性能的線索。
雖然沒有“複製到 tmp 表”,但有一個相當大的“打開表”。但不知道它是您的表還是tmp表。有“創建 tmp 表”。tmp 表可能在記憶體中;也就是說,沒有實際的磁碟表。
有兩種方法可以進行查詢 -
- 在所有的記憶體中建立一個雜湊
varcs
;掃描表,增加散列中的條目;對結果進行排序;傳遞它。- 首先對錶進行排序(在您的情況下,這涉及 RAM 中的 tmp 表);然後進行簡單的表掃描,一次建構一個
COUNT
。我不知道優化器何時會選擇一個。但它總是涉及表掃描,這往往是花費的大部分時間(儘管它沒有出現在配置文件中)。
如果你碰巧有
INDEX(varc)
,它會這樣做:
- 掃描該索引,一次建立一個計數。這將避免臨時表和任何形式的排序。
但是……當查詢時間低於 10 毫秒時,不值得剖析——獲得的東西很少,值得優化的東西也很少。