MySQL的邏輯架構

-
連接器:負責用戶的身份認證和權限校驗,
-
查詢快取:這個在8.0以后的版本已經取締了,但是不影響設計思想的了解,即:當有一個SQL進來的時候,先會去匹配SQL陳述句,如果本地已經有快取,即直接讀快取,回傳結果,乍一聽挺好的功能,為什么會被取締呢?這存在一些設計理念的問題,MySQL追求極高的性能,該功能在實際使用程序中弊大于利,寫快取/清快取的程序可能會大幅度影響性能
-
分析器/決議器:這個模塊主要是進行一些語法分析/詞法分析,大家可能覺得與自己關系不太大,其實我們初學SQL陳述句的時候第一個打交道的就是這個模塊,比如當你輸入錯誤陳述句的時候,語法的錯誤在這層就已經發現了,
-
前處理器:這個模塊會確定你輸入的表和列是否真實存在,欄位別名是否有歧義,主要是當你語法沒錯的時候,確定是否符合這個場景,
-
查詢優化器:這可以說是server層最核心也是實戰最重要的地方了,首先,我們每次可以通過explain+sql來查看當前陳述句的各個屬性,這些屬性能給我們調優很好的建議,這點會在下篇文章中細談,這篇文章總體是為了打通全鏈路,
其次,我們可以根據show warnings來查看查詢優化器到底做了哪些優化,從而考慮優化是否得當, -
執行引擎:這塊主要是對結果進行過濾和排序,這個模塊的命名有些歧義,其實真實的資料檢索并非在這里進行,這層進行的是對檢索的結果集進行一次過濾和排序,
-
存盤引擎:這里就是真正的核心了,也就是我們一直所說的innodb、myisam等存盤引擎作業的地方,我們所有的查詢檢索任務都是在這里進行的,所有的存盤也是在這里進行,這個模塊也會在之后的文章中分析,
現在來假設一條SQL來做全套了,那么它會是怎樣的一個邏輯呢?
首先我們客戶端與服務器之間會建立一個連接(這里的連接是指那幾種行程通信方式中的一種,大部分情況下說的是TCP/IP進行連接的,程序中需要我們mysql -u root -p輸入密碼,就可以進入mysql,
此時我們可以通過SQL陳述句進行增刪改查,當我們輸入一條陳述句,倘若在5.8版本之前,這條陳述句會進入查詢快取,在這個模塊中先對SQL陳述句進行匹配,倘若找到完全匹配的快取,則讀快取回傳結果,倘若沒有匹配的,則會進入下一模塊,查詢到的結果會寫進寫快取這也是之所以在5.8以后取締掉查詢快取的原因:寫快取對性能是有一定的影響的,事實上這個影響甚至大于其對速度的提升,
進入下一模塊以后,會對陳述句進入一些詞法分析和語法分析,看看有沒有語法上的錯誤,初學者經常被卡在這個模塊,因為陳述句寫的不規范之類的問題,
再到后來,這條陳述句會進入前處理器,也就是看看你雖然說的都對,語法都對,但是你搜索的列如果是我根本沒有的,那相當于什么都沒有,如果一切正常,就再往后走,
此時進入了server層最核心的查詢優化器,這里MySQL有自己的想法, 他會對你輸入的陳述句進行一些優化和重排,這里有一個很細節但是很核心的點:任何關聯進入查詢優化器都會變成嵌套回圈關聯,也就是說,很多復雜的關聯都會變成類似于左連接之類的關聯,其原因也非常簡單,正如上述:執行引擎是對結果進行過濾和排序,那么如果我們可以通過優化陳述句提前對陳述句進行過濾,這樣就可以大幅度提高性能,當我們查詢Explain+sql陳述句的時候會出現很多的屬性,我們需要注意的是要避免外部排序的產生,因為這樣會產生巨大的性能影響,
查詢優化器畢竟不是十全十美的,它的很多優化可能是好心沒做好事,最典型的就是臨時表了,首先臨時表這個東西本身是非常好的,它將中間程序的一些結果集存盤在記憶體上,很有利于查詢程序的執行,但是有可能記憶體不足的情況下,會將資料存盤在磁盤上,而磁盤參與讀寫一定會帶來非必要的資源和性能消耗,因此我們必須結合實際情況考究某些屬性的存在是否合理,
查詢優化器之后,查詢進入了執行引擎,在這里其實并未進行太多的事情,執行引擎主要是調度存盤引擎,然后存盤引擎在硬碟中去檢索,然后拿到結果回傳執行引擎,由執行引擎進行結果的過濾和排序,然后回傳結果集回到客戶端,如果是在5.8以前的話,會放入寫快取,
接下來就是核心的問題了:存盤引擎,
我們常用的存盤引擎大概是innodb和myisam,這兩任默認引擎撐起了MySQL的半邊天,現在我會比較粗略的介紹一下兩個引擎,詳細的文章會在后期輸出,
innodb存盤引擎與myisam存盤引擎
首先我們先認識所謂存盤引擎最重要的兩個功能就是存盤與查詢,那么我們從存盤和查詢兩個方面來分析一下這兩個引擎的特點,
存盤方面:
首先當我們存盤資料的時候,因為這兩個引擎都是基于磁盤的,innodb是將索引和資料放在一起的,這跟其索引結構有關,當進行存盤的時候,innodb將所有的資料都存盤在一起;而myisam則是將索引資料和真實資料分開存盤,這樣其實是通過索引進行檢索,得到的結果是一個真實資料的指標,然后進入資料檔案中進行隨機io,這就決定了一點,如果我們是innodb存盤引擎的話,主鍵盡量自增,因為如果非自增,會導致不能進行順序io,性能會有很大的退化,而myisam的資料存盤位置不能輕易移動,因為這樣會導致索引失效,也會影響性能,
查詢方面:
查詢就像翻詞典一樣,索引就像目錄和頁碼,這是非常重要的一部分,很多初學者覺得自己非常少用到索引,其實不然,我們經常用到的主鍵便是最標準的索引,當你的查詢命中索引的時候,便可以進入高速列車,為什么呢?因為資料結構,在此強調一下,一直很認同程式=資料結構+演算法,資料結構非常重要,如果我們能命中索引,就可以進入索引的資料結構,此時要么是哈希索引,要么是b+樹索引,這兩種索引一個的復雜度為O(1),一個是O(log(M)N),其中M為索引關鍵字,N為總關鍵字數量,很容易看到,這種速度比全表遍歷好了太多了,所以如果命中索引的話,就可以大幅度提高速率,
當然這兩點雖然重要,但是都不是兩種引擎最大的區別,這兩種存盤引擎最大的差別在于事務性和鎖的粒度上,這也是innodb彎道超車最重要的原因,
事務性
隨著資料庫的應用場景越來越多,我們對資料的安全性有了越來越多的需求,myisam不支持事務,這導致這種存盤引擎很快的落時了,
鎖粒度
并不是說myisam完全不考慮資料安全性,只是它的粒度有些太大了,它為了資料的安全直接動用了表級鎖,直接導致性能影響太大,
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/26189.html
標籤:MySQL
