MySQL查詢過程是什么-創(chuàng)新互聯(lián)

小編給大家分享一下MySQL查詢過程是什么,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

創(chuàng)新互聯(lián)建站2013年開創(chuàng)至今,先為句容等服務(wù)建站,句容等地企業(yè),進行企業(yè)商務(wù)咨詢服務(wù)。為句容企業(yè)網(wǎng)站制作PC+手機+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。

MySQL邏輯架構(gòu)

MySQL邏輯架構(gòu)整體分為三層,最上層為客戶層,并非MySQL所獨有,諸如,連接處理、授權(quán)認證、安全等功能均在這一層處理。

MySQL大多數(shù)核心服務(wù)均在中間這一層,包括查詢解析、分析、優(yōu)化、緩存、內(nèi)置函數(shù)(時間、數(shù)學、加密等),所有的跨存儲引擎的功能也在這一層實現(xiàn):存儲過程、觸發(fā)器、視圖等。

最下層為存儲引擎,其負責MySQL中的數(shù)據(jù)存儲和提取,中間的服務(wù)層通過API與存儲引擎通信,這些API接口屏蔽了不同存儲引擎的差異。

MySQL查詢過程

當向MySQL發(fā)送一個請求的時候:

MySQL查詢過程是什么

1.客戶端/服務(wù)端通信協(xié)議

MySQL客戶端/服務(wù)端通信協(xié)議是“半雙工”的:在任意時刻,要么是服務(wù)器向客戶端發(fā)送數(shù)據(jù),要么是客戶端向服務(wù)器發(fā)送數(shù)據(jù),這兩個動作不能同時發(fā)生。一旦一端開始發(fā)送消息,另一端要接受完整個消息才能響應(yīng)它,所以我們無法也無須將一個消息切成小塊獨立發(fā)送,也沒有辦法進行流量控制。

客戶端用一個單獨的數(shù)據(jù)包將查詢請求發(fā)送給服務(wù)器,所以當查詢語句很長的時候,需要設(shè)置max_allowed_packet參數(shù)。但是需要的注意的是,如果查詢實在是太大,服務(wù)端會拒絕接受更多數(shù)據(jù)并拋出異常。

與之相反的是,服務(wù)器響應(yīng)給用戶的數(shù)據(jù)通常會很多,由多個數(shù)據(jù)包組成。但是當服務(wù)器響應(yīng)客戶端請求時,客戶端必須完整的接受整個返回結(jié)果,而不能簡單的只取前面幾條結(jié)果,然后讓服務(wù)器停止發(fā)送。因而在實際開發(fā)中,盡量保持查詢簡單且只返回必需的數(shù)據(jù),減小通信間數(shù)據(jù)包的大小和數(shù)量是一個非常好的習慣,這也是查詢中盡量避免使用SELECT * 以及加上LIMIT限制的原因之一。

2.查詢緩存

在解析一個查詢語句前,如果查詢緩存是打開的,那么MySQL會檢查這個查詢語句是否命中查詢緩存中的數(shù)據(jù)。如果當前查詢恰好命中查詢緩存,在檢查一次用戶權(quán)限后直接返回緩存中的結(jié)果。這種情況下,查詢不會被解析,也不會生成執(zhí)行計劃,更不會執(zhí)行。

MySQL將緩存存放在一個引用表(類似于HashMap的數(shù)據(jù)結(jié)構(gòu)),通過一個哈希值索引,這個哈希值通過查詢本身、當前要查詢的數(shù)據(jù)庫、客戶端協(xié)議版本號等一些可能影響結(jié)果的信息計算得來。所以兩個查詢在任何字符上的不同(空格、注釋),都會導致緩存不會命中。

如果查詢中包含任何用戶自定義函數(shù)、存儲函數(shù)、用戶變量、臨時表、mysql庫中的系統(tǒng)表,其查詢結(jié)果都不會被緩存。比如函數(shù)NOW()或者CURRENT_DATE()會因為不同的查詢時間,返回不同的查詢結(jié)果,再比如包含CURRENT_USER或者CONNECION_ID()的查詢語句會因為不同的用戶而返回不同的結(jié)果,將這樣的查詢結(jié)果緩存起來沒有任何的意義。

3.緩存失效

MySQL的查詢緩存系統(tǒng)會跟蹤查詢中涉及的每個表,如果這些表(數(shù)據(jù)或結(jié)構(gòu))發(fā)生變化,那么和這張表相關(guān)的所有緩存數(shù)據(jù)都將失效。正因為如此,在任何的寫操作時,MySQL必須將對應(yīng)表的所有緩存都設(shè)置為失效。如果查詢緩存非常大或者碎片很多,這個操作就可能帶來很大的系統(tǒng)消耗,甚至導致系統(tǒng)僵死一會兒。而且查詢緩存對系統(tǒng)的額外消耗也不僅僅在寫操作,讀操作也不例外:

1.任何的查詢語句在開始之前都必須經(jīng)過檢查,即使這條SQL語句永遠不會命中緩存

2.如果查詢結(jié)果可以被緩存,那么執(zhí)行完成后,會將結(jié)果存入緩存,也會帶來額外的系統(tǒng)消耗

基于此,要知道并不是什么情況下查詢緩存都會提高系統(tǒng)性能,緩存和失效都會帶來額外消耗,只有當緩存帶來的資源節(jié)約大于其本身消耗的資源時,才會給系統(tǒng)帶來性能提升。但要如何評估打開緩存是否能夠帶來性能提升是一件非常困難的事情,。如果系統(tǒng)確實存在一些性能問題,可以嘗試打開查詢緩存,并在數(shù)據(jù)庫設(shè)計上做一些優(yōu)化:比如:

1.用多個小表代替一個大表,注意不要過度設(shè)計

2.批量插入代替循環(huán)單條插入

3.合理控制緩存空間大小,一般來說其大小設(shè)置為幾十兆比較合適

4.可以通過SQL_CACHE和SQL_NO_CACHE來控制某個查詢語句是否需要進行緩存

不要輕易打開查詢緩存,特別是寫密集型應(yīng)用。如果實在是忍不住,可以將query_cache_type 設(shè)置為DEMAND,這時只有加入SQL_CACH的查詢才會走緩存,其他查詢則不會,這樣可以非常自由地控制哪些查詢需要被緩存。

4.語法解析和預(yù)處理

MySQL通過關(guān)鍵字將SQL語句進行解析,并生成一顆對應(yīng)的解析樹。這個過程解析器主要通過語法規(guī)則來驗證和解析。比如SQL中是否使用了錯誤的關(guān)鍵字或者關(guān)鍵字的順序是否正確等等。預(yù)處理則會根據(jù)MySQL規(guī)則進一步檢查解析樹是否合法。比如檢查要查詢的數(shù)據(jù)表和數(shù)據(jù)列是否存在等等。

5.查詢優(yōu)化

語法樹被認為是合法之后,并且有優(yōu)化器將其轉(zhuǎn)化成查詢計劃,多數(shù)情況下,一條查詢可以有很多種執(zhí)行方式,最后都返回相應(yīng)的結(jié)果,優(yōu)化器的作用就是找到這其中最好的執(zhí)行計劃。

MySQL的查詢優(yōu)化器是一個非常復(fù)雜的部件,它使用了非常多的優(yōu)化策略來生成一個最優(yōu)的執(zhí)行計劃:

1.重新定義表的關(guān)聯(lián)順序(多張表關(guān)聯(lián)查詢時,并不一定按照SQL中指定的順序進行,但有一些技巧可以指定關(guān)聯(lián)順序)

2.優(yōu)化MIN()和MAX()函數(shù)(找某列的最小值,如果該列有索引,只需要查找B+Tree索引最左端,反之則可以找到大值)

3.提前終止查詢(使用Limit時,查找到滿足數(shù)量的結(jié)果集后會立即終止查詢)

4.優(yōu)化排序(在老版本MySQL會使用兩次傳輸排序,即先讀取行指針和需要排序的字段在內(nèi)存中對其排序,然后再根據(jù)排序結(jié)果去讀取數(shù)據(jù)行,而新版本采用的是單次傳輸排序,也就是一次讀取所有的數(shù)據(jù)行,然后根據(jù)給定的列排序)

6.查詢執(zhí)行引擎

在完成解析和優(yōu)化階段以后,MySQL會生成對應(yīng)的執(zhí)行計劃,查詢執(zhí)行引擎根據(jù)執(zhí)行計劃給出的指令逐步執(zhí)行得出結(jié)果。整個執(zhí)行過程的大部分操作均是通過調(diào)用存儲引擎實現(xiàn)的接口來完成,這些接口被稱為handler API。查詢過程中的每一張表由一個handler實例表示,實際上,MySQL在查詢優(yōu)化階段就為每一張表創(chuàng)建了一個handler實例,優(yōu)化器可以根據(jù)這些實例的接口來獲取表的相關(guān)信息,包括表的所有列名、索引統(tǒng)計信息等。存儲引擎接口提供了非常豐富的功能,但其底層僅有幾十個接口,這些接口像塔積木一樣完成了一次查詢的大部分操作。

7.返回結(jié)果給客戶端

查詢執(zhí)行的最后一個階段就是將結(jié)果返回給客戶端。即使查詢不到數(shù)據(jù),MySQL仍然會返回這個查詢的相關(guān)信息,比如該查詢影響到的行數(shù)以及執(zhí)行時間等等。

如果查詢緩存被打開且這個查詢可以被緩存,MySQL也會將結(jié)果存放到緩存中。

結(jié)果集返回客戶端是一個增量且逐步返回的過程。有可能MySQL在生成第一條結(jié)果時,就開始向客戶端逐步返回結(jié)果集了。這樣服務(wù)端就無須存儲太多結(jié)果而消耗過多內(nèi)存,也可以讓客戶端第一時間獲得返回結(jié)果。需要注意的是,結(jié)果集中的每一行都會以一個滿足①中所描述的通信協(xié)議的數(shù)據(jù)包發(fā)送,再通過TCP協(xié)議進行傳輸,在傳輸過程中,可能對MySQL的數(shù)據(jù)包進行緩存然后批量發(fā)送。

MySQL整個查詢執(zhí)行過程

1.客戶端向MySQL服務(wù)器發(fā)送一條查詢請求

2.服務(wù)器首先先檢查查詢緩存,如果命中緩存,則立刻返回存儲在緩存中的結(jié)果。否則進入下一級段

3.服務(wù)器進行SQL解析、預(yù)處理、再由優(yōu)化器生成對應(yīng)的執(zhí)行計劃

4.MySQL根據(jù)執(zhí)行計劃,調(diào)用存儲引擎的API來執(zhí)行查詢

以上是MySQL查詢過程是什么的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學習更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)網(wǎng)站制作公司行業(yè)資訊頻道!

新聞標題:MySQL查詢過程是什么-創(chuàng)新互聯(lián)
分享地址:http://bm7419.com/article34/cdgipe.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站改版做網(wǎng)站、外貿(mào)建站品牌網(wǎng)站制作、電子商務(wù)、網(wǎng)站設(shè)計公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

手機網(wǎng)站建設(shè)