深入瞭解mysql中sql查詢語句是如何工作的?

寫sql語句或許是很多後端程序員都需要做的事情,但是經常寫sql語句的你知道一條sql查詢語句是如何執行的嗎?本篇文章帶你一探究竟

首先帶着問題去學習:下面的sql再簡單不過了,執行完這條sql,你會得到一個結果。那麼這個結果是如何產生的呢?

select * from T where id = 1;

先給大家看一張mysql基本的架構圖

 

總體來說:mysql可以分爲server層和存儲引擎層

server層主要包含連接器,分析器,優化器,執行器等。跨存儲引擎的功能都在server層實現,包括內置函數(時間,文本),觸發器,存儲過程,視圖。

存儲引擎層被mysql設計爲可插拔式的,mysql5.5.5版本後默認使用InnoDB,因爲InnoDB支持事務。還有其他類型比如MyISAM、Memory等。存儲引擎層主要負責數據的讀寫。

圖中很容易看到,存儲引擎使用的是相同的server層。

第一步:連接器

毫無疑問,執行sql語句首先需要建立一個連接,這個時候連接器會等待你。連接器負責跟客戶端建立連接、獲取權限、維持和管理連接。

當你輸入用戶名,密碼後,連接器會先驗證用戶名和密碼是否正確。通過身份認證後,連接器還會去權限表中查詢你的權限。言外之意,連接成功後的權限信息都依賴於連接器的這次查詢,如果管理員修改了你的權限,在下次重新登錄後才能生效。

需要注意的是,數據庫的連接比較耗費性能,所以纔有了許許多多數據庫連接池的出現。

第二步:緩存查詢

建立連接之後,mysql會拿到你的select語句,然後去查詢緩存,查看一下之前是否執行過該語句。mysql的查詢緩存會以key-value的形式存放在內存中。key是select語句,value是查詢的結果集。如果找到相同的key就將結果直接返回,沒有找到就進行下一步操作。

你會發現,在同一個連接中,執行相同的select,後來執行select的時間會比第一次查詢的時間快很多,這就是緩存的作用。

需要注意的是:並不是任何時候都適合使用緩存。因爲緩存會失效,一旦一張表中有新的數據變動,就會導致緩存失效。如果一張表更新的次數比查詢的次數多,就不建議使用緩存。想象一下這種情況,你好不容易將數據緩存起來了,結果還沒有使用就消失了,得不償失。

MySQL提供了這種“按需使用”的方式。你可以將參數 query_cache_type 設置成 DEMAND,這樣對於默認的 SQL 語句都不使用查詢緩存。而對於你確定要使用查詢緩存的語句,可以用 SQL_CACHE 顯式指定,像下面這個語句一樣:

select SQL_CACHE * from T where id = 1;

第三步:分析器

在第二步如果沒有命中緩存,就會對select語句進行詞法分析。分析器需要辨別T代表着查詢的表,id代表查詢的列。做完詞法分析後會進行語法分析,主要是判斷你輸入的語句是否符合mysql的語法要求,如果不符合就直接報錯。

第四步:優化器

優化器主要是對查詢進行優化,比如索引的選擇,表的關聯順序。優化器會判斷如何更高效的執行語句。本篇文章暫時不涉及sql語句優化,下面文章會詳細介紹。

第五步:執行器

MySQL通過第三步的分析器知道了你要做什麼,通過第四步優化器知道了該怎麼做,於是就進入了執行器階段,開始執行語句。

執行語句的時候,會先判斷一下你對查詢的表T有沒有執行查詢的權限,如果沒有,就會返回沒有權限的錯誤。注意,在第二步查詢緩存的時候,會在返回結果的時候做權限驗證。

然後執行器就會調用存儲引擎提供的接口進行語句查詢。

針對剛開始寫的select查詢,執行器執行的步驟如下:

 

select * from T where id = 1;

假設id沒有索引

1.調用引擎接口,找到對應的表,拿到該表的第一行數據,判斷id是否等於1,不是則跳過,是則將數據存放在結果集中

2.繼續掃描下一行,判斷是否符合條件,直到將全表掃描完成。

3.將所有的結果返回給客戶端。

假設id有索引

1.如果你大致瞭解索引的話,其實索引就相當於書本的目錄,可以大大縮減查詢的範圍。如果有索引的話,首先會大致確定掃描的行數。

2.開始一行一行的掃描,尋找符合條件的數據。

3.將所有的結果返回給客戶端。

在分析一條語句的時候,你可以使用explain進行解釋,查看該語句掃描的行數。

 

 

結束了------------

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