一条简单的 SQL 查询语句到底经历了什么?
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                一条简单的 SQL 查询语句到底经历了什么?
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.                        
                                一、MySQL 基礎(chǔ)架構(gòu)
整體來(lái)說(shuō) MySQL 主要分為兩個(gè)部分,一個(gè)部分是:Server 層,另一部分是:存儲(chǔ)引擎層。
其中 Server 層包括有連接器、查詢緩存、分析器、優(yōu)化器、執(zhí)行器等,存儲(chǔ)引擎層支持 InnoDB、MyISAM、Memory 等。
現(xiàn)在最常用的存儲(chǔ)引擎是 InnoDB,同時(shí)也是 MySQL 默認(rèn)的存儲(chǔ)引擎。
通過(guò)分析器知道要做什么。
通過(guò)優(yōu)化器知道怎么做。
通過(guò)執(zhí)行器調(diào)用存儲(chǔ)引擎接口,進(jìn)行數(shù)據(jù)的查詢。
俗話說(shuō):"一圖勝千言",我們還是來(lái)看下面這張流程圖吧。
注: MySQL 8.0 版本已經(jīng)將查詢緩存功能移除了。
二、SQL 語(yǔ)句執(zhí)行流程
1、情形一
下面我們通過(guò)一條 SQL 語(yǔ)句來(lái)分析它在 MySQL 中的執(zhí)行流程:
例如:select * from user where name = "yxhsea";
首先,客戶端通過(guò) TCP 的三次握手連接上 MySQL 服務(wù),通過(guò)連接器進(jìn)行權(quán)限驗(yàn)證。
驗(yàn)證通過(guò)之后,客戶端發(fā)送 SQL 語(yǔ)句到 MySQL 服務(wù)端,通過(guò)緩存器判斷是否緩存了 name 是 yxhsea 的數(shù)據(jù),
如果命中緩存,則直接將結(jié)果返回給客戶端,否則,SQL 語(yǔ)句通過(guò)分析器進(jìn)行詞法分析、語(yǔ)法分析,
將 select、from、where 這些關(guān)鍵字識(shí)別出來(lái),把 user 識(shí)別為表名,name 識(shí)別為列名。
之后,SQL 語(yǔ)句通過(guò)優(yōu)化器選擇合適的索引,生成具體的執(zhí)行計(jì)劃。
最后,SQL 語(yǔ)句到達(dá)執(zhí)行器調(diào)用存儲(chǔ)引擎的查詢接口,將查詢到的數(shù)據(jù)返回給客戶端。
2、情形二
我們分析下面這條 SQL 語(yǔ)句的執(zhí)行流程:
select id from user where age between 10 and 20;
1、首先,在 age 索引樹(shù)上找到 age 等于 10 的節(jié)點(diǎn)。
2、然后,再到 age 索引樹(shù)上繼續(xù)尋找下一個(gè)節(jié)點(diǎn),直到 age 大于 20 時(shí)循環(huán)結(jié)束。
3、最后,返回 age 是 10 到 20 之間的查詢結(jié)果。
上面這種情況,屬于覆蓋索引。
顧名思義,覆蓋索引就是要查詢的數(shù)據(jù)就存儲(chǔ)在索引樹(shù)上,不需要進(jìn)行回表操作。
3、情形三
那什么情況下就需要進(jìn)行回表呢?我們來(lái)分析下面這條 SQL 語(yǔ)句:
select * from user where age between 10 and 20;
1、首先,在 age 索引樹(shù)上找到 age 等于 10 的節(jié)點(diǎn),獲取到 ID 等于 1。
2、然后,到 ID 索引樹(shù)上找到 ID 等于 1 的節(jié)點(diǎn),獲取行記錄。
3、之后,再回到 age 索引樹(shù)上,尋找下一個(gè)節(jié)點(diǎn) age 等于 20,獲取到 ID 等于 2 (再重復(fù)第 2 步)。
4、依次類推 (再重復(fù)第 1、2 步),循環(huán)遍歷直到 age 大于 20 時(shí),循環(huán)結(jié)束。
5、最后,將在 ID 索引樹(shù)上查詢到的行記錄作為結(jié)果返回。
這里的流程當(dāng)中的,回到 ID 索引樹(shù)上查詢行記錄的過(guò)程,稱之為回表。
注:使用 * 查詢數(shù)據(jù)會(huì)導(dǎo)致回表,所以我們?cè)诓樵償?shù)據(jù)的時(shí)候,盡量指定具體的字段覆蓋索引。
四、結(jié)語(yǔ)
我們?cè)谶@里介紹了 MySQL 的基本架構(gòu),以及一條簡(jiǎn)單 SQL 語(yǔ)句的執(zhí)行流程。因此我們?cè)谄匠>帉?xiě) SQL 語(yǔ)句的過(guò)程中,應(yīng)該盡量使用覆蓋索引的方式,來(lái)避免回表查詢?cè)斐深~外的磁盤開(kāi)銷。當(dāng)然這篇文章也只是介紹了 SQL 語(yǔ)句執(zhí)行流程的一小分部?jī)?nèi)容,其中涉及到鎖、事務(wù)等并未展開(kāi)講述。以上純是我的淺知拙見(jiàn),如有不妥,敬請(qǐng)斧正。
總結(jié)
以上是生活随笔為你收集整理的一条简单的 SQL 查询语句到底经历了什么?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: 《NVMe-over-Fabrics-1
- 下一篇: 抽取JDBC工具类
