MySQL是如何執行查詢的

原文鏈接:http://www.xaprb.com/blog/2009/04/01/how-mysql-really-executes-a-query/

 

:作者說了,很多地方是愚人節的玩笑...

 

讓我們看看它是如何從開始到結束的。

 

SELECT SQL_NO_CACHE COUNT(col1) FROM users
WHERE userid IN(
   SELECT userid FROM othertbl
)
ORDER BY userid DESC;

 

執行這個查詢可以分爲以下的幾步:

   1. MySQL API將查詢分解成一系列標記併發送到server。
   2. 解析查詢
   3. MySQL進行權限檢查。由於可能要調用一次LDAP或者活動目錄,所以此步比較複雜。這裏先註釋掉這一步。
   4. 查詢緩存進行檢查。但是由於我明確的給出了SQL_NO_CACHE的指令,所以查詢緩存再次並不檢查。(如果沒有給出SQL_NO_CACHE指令,可能會在緩存中找到一個結果集並返回它。)
   5. 優化器執行子查詢並返回userid值的列表替換掉IN表達式。
   6. 優化器開始處理COUNT 表達式。就我們所知,所有的COUNT查詢在MyISAM表上都能被非常快速的執行,但又有InnoDB並沒有優化器,所以在InnoDB上COUNT是比較慢的。實際上,InnoDB在各方面都比MyISAM慢,所以應該經常使用MyISAM。
   7. 經過解析並優化的查詢被編譯成查詢計劃(query plan | 譯者: execution plan)—— 本地的字節碼,可以直接在CPU上執行。
   8. 優化過的查詢計劃被保存下來留爲之後的查詢用。如果稍後一個相似的查詢發送過來,解析和編譯可以被省略。而令人奇怪的是,這些都是存放在查詢緩存中的。(這僅僅是那些存放在查詢緩存中有趣的之一,正如我所說,執行可能並不如你所願)
   9. 查詢被執行,可能是多個CPU同時執行。如果這樣的話,多個CPU的放回結果需要被結合成最終結果。此處的操作會顯示在Sort_merge_passes狀態中。(這就是爲什麼sort_buffer_size要設置的比較大,一般我推薦是可用內存的75%或者更多。)
   10. 如果userid列上沒有索引,那麼 ORDER BY 會被忽略。但如果有索引的話,MySQL的行鎖和MVCC(server實現,並不在存儲引擎中)將強制從索引中讀取結果。在這種情況下,結果會被放置到一個文件中並被排序,內部名稱是“filesort”,可以在EXPLAIN的輸出中看到。
   11. 如果結果集比server的內存大,server也必須在磁盤上創建臨時表。那樣,在EXPLAIN的輸出中將可以看到“Using temporary; Using disk table”。
   12. 通過一個分離的網絡連接返回結果集給客戶端(如此,查詢才能異步)。
   13. 查詢結束後,記錄在MyISAM的事務日誌——binary log中。如果你記錄了這些log,你可以撤銷之前執行的語句,如此便不需要備份了。可以僅僅用binary log來回滾修改。binary log也是MyISAM的優勢之一。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章