mysql執行sql語句過程

w39發表於2021-09-09

開發人員基本都知道,我們的資料存在資料庫中(目前最多的是mysql和oracle,由於作者更擅長mysql,所以這裡預設資料庫為mysql),伺服器透過sql語句將查詢資料的請求傳入到mysql資料庫。資料庫拿到sql語句以後。都是進行了哪些操作呢?這裡向大家介紹下我的個人的理解,歡迎大家評論區批評指正。

流程概述

  mysql得到sql語句後,大概流程如下:

  1.sql的解析器:負責解析和轉發sql

  2.前處理器:對解析後的sql樹進行驗證

  3.查詢最佳化器:得到一個執行計劃

  4.查詢執行引擎:得到資料結果集

  5.將資料放回給呼叫端。

流程圖如下所示:

圖片描述

分發器及快取階段

  首先,如果系統的快取功能開啟著的話,sql語句進入mysql後,sql進行判斷,是否為select關鍵字。如果是,那麼先去查詢快取中進行查詢,如果在查詢快取中可以命中sql語句,那麼直接返回查詢快取中的查詢語句對應的value值(在快取中,把查詢語句做一個hash運算,結果作為key值,查詢的結果集為value)。

  如果命中快取的話,查詢速度是相當快的。但是查詢快取也有它相應的缺點。

  首先,開啟快取的話,伺服器會消耗大量的記憶體空間;其次,快取有的時候並不適用;最後,有的情況下,開啟快取也不會將對應的sql語句寫入快取。

快取不適用的情況:

  快取的鎖的力度比較大,而且對於動態sql的支援度不夠。

  快取在資料進行更新的時候,是進行的表級鎖,更新結束後,會把所有與更新內容相關的快取全部刪除。所以,如果表的寫入比較多的話,快取是比較浪費效能的。如果寫入特別多,可能快取反而會導致mysql變慢。

查詢不到快取的情況:

  1.查詢條件有不確定資料:如now ,current_time等。

  2.快取對大小寫敏感,如select * from test 和SELECT* FROM test 就不會解析為同一條sql

查詢帶來的額外開銷:

  1.開始前需要先檢查快取是否命中。

  2.結果輸出的時候,需要額外進行資料的快取操作。

  3.寫入資料時,mysql會將對應表的所有快取都設定為失效。當快取記憶體較大的時候,會導致系統消耗較大。

sql的解析器與預處理

  sql解析器是在命令分發之後,將對應的sql語句,解析為sql解析樹。sql解析樹是Mysql本身內部的語法規則和解析查詢。驗證是否使用錯誤的關鍵字,sql語法順序是否正確等。(語法層面的錯誤)

  解析完成後,進行查詢語句前處理器,根據mysql的規則,檢查解析樹是否合法。(表格是否存在,別名是否有歧義等)

查詢最佳化器

  查詢最佳化器獲取到執行計劃然後由查詢執行引擎執行相應的操作。查詢最佳化器,是資料庫l的一個核心模組,分為cbo和rbo兩種。

  其中,rbo是基於規則的最佳化器。(rbo在oracle早期版本中使用,現在也保留,不過預設為cbo。mysql沒有rbo最佳化器)

  這些規則是硬編碼在資料庫的程式碼中的。rbo會根據輸入的sql語句可以匹配到的優先順序最高的規則去作為執行計劃。例如:在rbo中有這麼一條規則:有索引的情況下,使用索引。那麼所有的帶有索引的表在執行的時候,都會走索引。rbo最大的問題在於,透過固定規則來決定執行計劃。並不會考慮sql中涉及的物件的數量和分佈。有可能選出來的規則不是最優的執行計劃。

  cbo 是基於成本的最佳化器(基於統計資訊),從目標諸多的執行路徑中選擇一個成本最小的執行路徑來作為執行計劃。成本指的是mysql根據相關的統計資訊,算出來sql語句對應的io,cpu等的消耗的一個估計值。計算過程涉及到索引、表、行等資料,過程比較複雜。

  1.查詢最佳化器使用統計資訊為sql選擇執行計劃。

  2.mysql沒有資料直方圖,也無法手工刪除統計資訊。(oracle有)

  3.在伺服器曾有查詢最佳化器,卻沒有儲存資料和索引統計資訊。統計資訊由儲存引擎實現,不同的儲存引擎會儲存不同的統計資訊。

  4.統計資訊分為索引的統計資訊和表的統計資訊。

檢視統計資訊

  索引統計資訊

  show index from table 或information_schema.statistics表

  表統計資訊

  show table status like 或 information_schema.tables表

查詢執行引擎+返回資料給客戶端

  得到執行計劃後,根據已有的執行計劃,查詢執行引擎,mysql的SQL Layer層,呼叫Storage Engine Layer層的介面,從mysql的儲存引擎中獲取到相對應的結果集,然後返回給使用者。

  執行完成後,將結果返回給客戶端,如果是查詢語句,並且開啟了快取,那麼,mysql會同時將結果集放到查詢快取中。然後將查到的結果集返回。如果是增刪改操作,那麼返回執行語句後受影響的行數。

文章來源:http://www.cnblogs.com/liyasong/


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/854/viewspace-2814038/,如需轉載,請註明出處,否則將追究法律責任。

相關文章