国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

MYSQL執(zhí)行一條SELECT語句的具體流程

這篇具有很好參考價值的文章主要介紹了MYSQL執(zhí)行一條SELECT語句的具體流程。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

昨天CSDN突然抽風(fēng)?我一個ctrl+z把整篇文章給撤掉了還不能復(fù)原?直接心態(tài)崩了不想寫了?不過這部分果然還是很重要,還是寫出來吧

流程圖?

MYSQL執(zhí)行一條SELECT語句的具體流程,mysql,數(shù)據(jù)庫

這里面總共有兩層結(jié)構(gòu)Server層?儲存引擎

  • Server 層負(fù)責(zé)建立連接、分析和執(zhí)行 SQL。MySQL 大多數(shù)的核心功能模塊都在這實現(xiàn),主要包括連接器,查詢緩存、解析器、預(yù)處理器、優(yōu)化器、執(zhí)行器等。另外,所有的內(nèi)置函數(shù)(如日期、時間、數(shù)學(xué)和加密函數(shù)等)和所有跨存儲引擎的功能(如存儲過程、觸發(fā)器、視圖等。)都在 Server 層實現(xiàn)。
  • 存儲引擎層負(fù)責(zé)數(shù)據(jù)的存儲和提取。支持 InnoDB、MyISAM、Memory 等多個存儲引擎,不同的存儲引擎共用一個 Server 層。現(xiàn)在最常用的存儲引擎是 InnoDB,從 MySQL 5.5 版本開始, InnoDB 成為了 MySQL 的默認(rèn)存儲引擎。我們常說的索引數(shù)據(jù)結(jié)構(gòu),就是由存儲引擎層實現(xiàn)的,不同的存儲引擎支持的索引類型也不相同,比如 InnoDB 支持索引類型是 B+樹 ,且是默認(rèn)使用,也就是說在數(shù)據(jù)表中創(chuàng)建的主鍵索引和二級索引默認(rèn)使用的是 B+ 樹索引。

第一步:連接器?

就是用戶和MYSQL相連接的過程,會發(fā)生三次握手和四次揮手,因為連接是基于TCP協(xié)議進(jìn)行傳輸?shù)?/p>

# -h 指定 MySQL 服務(wù)得 IP 地址,如果是連接本地的 MySQL服務(wù),可以不用這個參數(shù);
# -u 指定用戶名,管理員角色名為 root;
# -p 指定密碼,如果命令行中不填寫密碼(為了密碼安全,建議不要在命令行寫密碼),就需要在交互對話里面輸入密碼
mysql -h$ip -u$user -p

?如果 MySQL 服務(wù)正常運行,完成 TCP 連接的建立后,連接器就要開始驗證你的用戶名和密碼,如果用戶名或密碼不對,就收到一個"Access denied for user"的錯誤,然后客戶端程序結(jié)束執(zhí)行。

如果用戶密碼都沒有問題,連接器就會獲取該用戶的權(quán)限,然后保存起來,后續(xù)該用戶在此連接里的任何操作,都會基于連接開始時讀到的權(quán)限進(jìn)行權(quán)限邏輯的判斷。

所以,如果一個用戶已經(jīng)建立了連接,即使管理員中途修改了該用戶的權(quán)限,也不會影響已經(jīng)存在連接的權(quán)限。修改完成后,只有再新建的連接才會使用新的權(quán)限設(shè)置。

可以通過

 SHOW PROCESSLIST;

查看有多少用戶連接了MYSQL

MYSQL執(zhí)行一條SELECT語句的具體流程,mysql,數(shù)據(jù)庫

比如上圖的顯示結(jié)果,共有兩個用戶名為 root 的用戶連接了 MySQL 服務(wù),其中 id 為 6 的用戶的 Command 列的狀態(tài)為?Sleep?,這意味著該用戶連接完 MySQL 服務(wù)就沒有再執(zhí)行過任何命令,也就是說這是一個空閑的連接,并且空閑的時長是 736 秒( Time 列)。

空閑連接會一直占用著嗎?

當(dāng)然不是了,MySQL 定義了空閑連接的最大空閑時長,由?wait_timeout?參數(shù)控制的,默認(rèn)值是 8 小時(28880秒),如果空閑連接超過了這個時間,連接器就會自動將它斷開。

mysql> show variables like 'wait_timeout';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout  | 28800 |
+---------------+-------+
1 row in set (0.00 sec)

當(dāng)然,我們自己也可以手動斷開空閑的連接,使用的是 kill connection + id 的命令。

長鏈接和短連接的區(qū)別

短連接
連接 mysql 服務(wù)(TCP 三次握手)
執(zhí)行sql
斷開 mysql 服務(wù)(TCP 四次揮手)

// 長連接
連接 mysql 服務(wù)(TCP 三次握手)
執(zhí)行sql
執(zhí)行sql
執(zhí)行sql
....
斷開 mysql 服務(wù)(TCP 四次揮手)

所以就是短連接只有一條SQL語句?長連接有多條SQL語句

同樣一個任務(wù)我們使用長連接要比使用短連接節(jié)省了多次連接和斷開MYSQL的過程

但是長連接就一點缺點沒有嗎?非也

MySQL 在執(zhí)行查詢過程中臨時使用內(nèi)存管理連接對象,這些連接對象資源只有在連接斷開時才會釋放。如果長連接累計很多,將導(dǎo)致 MySQL 服務(wù)占用內(nèi)存太大,有可能會被系統(tǒng)強(qiáng)制殺掉,這樣會發(fā)生 MySQL 服務(wù)異常重啟的現(xiàn)象。

那我們?nèi)绾谓鉀Q這種問題嗎

斷開連接不就完事了嘛

1.定期手動斷開連接

2.客戶端主動重置連接。MySQL 5.7 版本實現(xiàn)了?mysql_reset_connection()?函數(shù)的接口,注意這是接口函數(shù)不是命令,那么當(dāng)客戶端執(zhí)行了一個很大的操作后,在代碼里調(diào)用 mysql_reset_connection 函數(shù)來重置連接,達(dá)到釋放內(nèi)存的效果。這個過程不需要重連和重新做權(quán)限驗證,但是會將連接恢復(fù)到剛剛創(chuàng)建完時的狀態(tài)。

每次學(xué)XX底層原理的時候都感覺,底層運行在替我負(fù)重前行

第二步:查詢緩存?

連接工作結(jié)束之后,客戶端就可以向MYSQL發(fā)送SQL語句了?它首先會解析語句的第一個字段?查看這是一條什么語句 假如說發(fā)送的是一個SELECT語句?那么它就會去去查詢緩存( Query Cache )里查找緩存數(shù)據(jù),看看之前有沒有執(zhí)行過這一條命令,這個查詢緩存是以 key-value 形式保存在內(nèi)存中的,key 為 SQL 查詢語句,value 為 SQL 語句查詢的結(jié)果。

如果查詢的語句命中查詢緩存,那么就會直接返回 value 給客戶端。如果查詢的語句沒有命中查詢緩存中,那么就要往下繼續(xù)執(zhí)行,等執(zhí)行完后,查詢的結(jié)果就會被存入查詢緩存中。

這么一看?這太牛了?這個查詢緩存?這不就像dp數(shù)組一樣可以大量優(yōu)化運行了嗎

其實不然?因為每次對這張表更新數(shù)據(jù)的時候?這張表的緩存就會被全部清除....啊?也就是說?如果是更新后的數(shù)據(jù)查不到?只能是未更新的查詢過一次的數(shù)據(jù)?

?那我查它干啥?我直接把上一次的查詢結(jié)果拿出來用多好

很好?MYSQL也是這么想的?所以MYSQL8.0直接把這個東西給刪了

第三步:解析SQL

第一件事:詞法分析,MYSQL會分析你這個SQL語句中的關(guān)鍵子?然后形成SQL語法樹 這樣方便后面模塊獲取 SQL 類型、表名、字段名、 where 條件等等。?(給MYSQL來一把長難句分析)

第二件事:句法分析?就是看有沒有語法錯誤

這里加粗了語法錯誤?字段,表,數(shù)據(jù)不存在那不是語法錯誤哦

就像JVM中的元數(shù)據(jù)驗證?字節(jié)碼驗證一樣

第四步:執(zhí)行 SQL

MYSQL執(zhí)行一條SELECT語句的具體流程,mysql,數(shù)據(jù)庫

對應(yīng)圖中的四塊

  • prepare 階段,也就是預(yù)處理階段;
  • optimize 階段,也就是優(yōu)化階段;
  • execute 階段,也就是執(zhí)行階段;

預(yù)處理階段?

?那肯定在預(yù)處理器中,于SELECT而言?預(yù)處理就做倆事

1.查看字段,表等數(shù)據(jù)是否存在

2.把*?替換成全部列

優(yōu)化階段

對應(yīng)的當(dāng)然是優(yōu)化器

我們知道MYSQL執(zhí)行語句的時候賊麻煩?又要判斷這個索引又判斷那個長度的?就是這一步?要確定一個執(zhí)行的具體方案

我們可以在查詢語句最前面加個?explain?命令,這樣就會輸出這條 SQL 語句的執(zhí)行計劃,然后執(zhí)行計劃中的 key 就表示執(zhí)行過程中使用了哪個索引?若果這個key參數(shù)是null的話?就說明沒有使用索引?也就是說?使用的是效率最差的全表查詢

具體來講?優(yōu)化器會選擇什么方案呢?

SELECT id FROM product WHERE id > 1  AND name LIKE 'i%';

這條查詢語句的結(jié)果既可以使用主鍵索引,也可以使用普通索引,但是執(zhí)行的效率會不同。這時,就需要優(yōu)化器來決定使用哪個索引了。

這里使用的是覆蓋索引,也就是說?同時使用這兩個索引 這兩個索引上的信息足夠滿足查詢請求,不需要再回到主鍵索引上去取數(shù)據(jù)。(查詢主鍵索引的 B+ 樹的成本會比查詢二級索引的 B+ 的成本大,優(yōu)化器基于查詢成本的考慮,會選擇查詢代價小的普通索引。)

就是個啥流程呢?首先先在二級索引(name)中?找到匹配的數(shù)據(jù)?然后二級索引存的數(shù)據(jù)就是主鍵id?然后記錄id>1的數(shù)據(jù)?所以就不用再去主鍵索引了?直接就出結(jié)果了

執(zhí)行階段?

執(zhí)行階段?那肯定是執(zhí)行器

經(jīng)歷過優(yōu)化器了?我們已經(jīng)得到了執(zhí)行方案?那現(xiàn)在就是正式的執(zhí)行SQL的時機(jī)了

執(zhí)行的過程中,執(zhí)行器就會和存儲引擎交互了,交互是以記錄為單位的。

攏共有三種執(zhí)行方式:

  • 主鍵索引查詢
  • 全表掃描
  • 索引下推

主鍵索引查詢

從語文的角度分析?他肯定是通過主鍵索引查詢的對吧(?)

我們看這行代碼

select * from product where id = 1;

?首先id為主鍵?肯定為1?再有這個篩選條件是等值?所以一定只會查詢一次

執(zhí)行器第一次查詢?調(diào)用read_first_record 函數(shù)指針指向的函數(shù)

這個函數(shù)指針被指向為 InnoDB 引擎索引查詢的接口(優(yōu)化器參數(shù)為const?有這個參數(shù)?儲存引擎才能選擇對應(yīng)的執(zhí)行方式),把條件?id = 1?交給存儲引擎,讓存儲引擎定位符合條件的第一條記錄。然后呢儲存引擎通過主鍵索引(b+樹)找到id為1的數(shù)據(jù)

判斷1:如果記錄是不存在的,就會向執(zhí)行器上報記錄找不到的錯誤,然后查詢結(jié)束。如果記錄是存在的,就會將記錄返回給執(zhí)行器;

然后如果存在的話?判斷2

查看是否符合篩選條件?如果符合發(fā)送給客戶端,如果不符合則跳過該記錄。

執(zhí)行器查詢的過程是一個 while 循環(huán),所以還會再查一次,但是這次因為不是第一次查詢了,所以這次會調(diào)用 read_record 函數(shù)指針指向的函數(shù)(區(qū)別于上面的read_first_record),因為優(yōu)化器選擇的訪問類型為 const(前面提到的這個參數(shù)再次出現(xiàn)),這個函數(shù)指針被指向為一個永遠(yuǎn)返回 - 1 的函數(shù),所以當(dāng)調(diào)用該函數(shù)的時候,執(zhí)行器就退出循環(huán),也就是結(jié)束查詢了

全表掃描

select * from product where name = 'iphone';

第一步不變?還是調(diào)用 read_first_record 函數(shù)指針指向的函數(shù)?但是這次因為是全表掃描(優(yōu)化器參數(shù)為all)

第二步?從第一條記錄開始讀取,看它是否滿足WHERE條件(name =?iPhone)?如果不滿足跳過,滿足把這條記錄發(fā)給客戶端

執(zhí)行器查詢的過程是一個 while 循環(huán),所以還會再查一次,會調(diào)用 read_record 函數(shù)指針指向的函數(shù),因為優(yōu)化器選擇的訪問類型為 all,read_record 函數(shù)指針指向的還是 InnoDB 引擎全掃描的接口,所以接著向存儲引擎層要求繼續(xù)讀剛才那條記錄的下一條記錄,存儲引擎把下一條記錄取出后就將其返回給執(zhí)行器(Server層),執(zhí)行器繼續(xù)判斷條件,不符合查詢條件即跳過該記錄,否則發(fā)送到客戶端;一直重復(fù)上述過程,直到存儲引擎把表中的所有記錄讀完,然后向執(zhí)行器(Server層) 返回了讀取完畢的信息; 執(zhí)行器收到存儲引擎報告的查詢完畢的信息,退出循環(huán),停止查詢。?

索引下推

它是MySQL 5.6 推出的查詢優(yōu)化策略

select * from t_user  where age > 20 and reward = 100000

假如說我們創(chuàng)建了?對于age和reward的索引

聯(lián)合索引當(dāng)遇到范圍查詢 (>、<) 就會停止匹配,也就是?age 字段能用到聯(lián)合索引,但是 reward 字段則無法利用到索引(硬記就行?后面可能會更新索引失效的部分)

如果不使用索引下推

第一步還是:?server層調(diào)用儲存引擎?找到滿足age>20的第一條記錄

第二步:存儲引擎根據(jù)二級索引的 B+ 樹快速定位到這條記錄后,獲取主鍵值,然后進(jìn)行回表操作,將完整的記錄返回給 Server 層

第三步:

server再判斷reward是否等于100000 如果符合?返回給用戶?不符合忽略

第四步:接著拿下一條記錄(不需要再次定位記錄了?記錄之間由鏈表連接)?存儲引擎在二級索引定位到記錄后,獲取主鍵值,然后回表操作拿到全部記錄數(shù)據(jù) 判斷是否符合

然后三四步循環(huán)?直到age>20的記錄查詢完畢

沒有索引下推的時候,每查詢到一條二級索引記錄,都要進(jìn)行回表操作,然后將記錄返回給 Server,接著 Server 再判斷該記錄的 reward 是否等于 100000

那么有索引下推的時候呢?

Server 層首先調(diào)用存儲引擎的接口定位到滿足查詢條件的第一條二級索引記錄,也就是定位到 age > 20 的第一條記錄;

存儲引擎定位到二級索引后,先不執(zhí)行回表操作,而是先判斷一下該索引中包含的列(reward列)的條件(reward 是否等于 100000)是否成立。如果條件不成立,則直接跳過該二級索引。如果成立,則執(zhí)行回表操作,將完成記錄返回給 Server 層。

Server 層在判斷其他的查詢條件(本次查詢沒有其他條件)是否成立(為什么只有reward條件可以用儲存引擎判斷呢??因為它雖然沒用上聯(lián)合索引?但是索引的數(shù)據(jù)還是有的?在聯(lián)合索引中對著id找reward還是很方便的(一對一對應(yīng)的)),如果成立則將其發(fā)送給客戶端;否則跳過該記錄,然后向存儲引擎索要下一條記錄。 如此往復(fù),直到存儲引擎把表中的所有記錄讀完。

就相當(dāng)于把判斷reward是否等于100000這件事外包給儲存引擎了

索引下推能夠減少二級索引在查詢時的回表操作,提高查詢的效率,因為它將 Server 層部分負(fù)責(zé)的事情,交給存儲引擎層去處理了文章來源地址http://www.zghlxwxcb.cn/news/detail-521910.html

到了這里,關(guān)于MYSQL執(zhí)行一條SELECT語句的具體流程的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • MySQL面試題:一條SQL語句在MySQL中執(zhí)行過程全解析

    MySQL面試題:一條SQL語句在MySQL中執(zhí)行過程全解析

    介紹一下下圖涉及的一些組件的基本作用幫助大家理解這幅圖。 連接/線程處理(連接器): 身份認(rèn)證和權(quán)限相關(guān)(如連接處理、授權(quán)認(rèn)證、安全等等)。 查詢緩存: 執(zhí)行查詢語句的時候,會先查詢緩存(MySQL 8.0 版本后移除)。 解析器: 沒有命中緩存的話,SQL 語句就會經(jīng)過解析

    2024年02月03日
    瀏覽(53)
  • MySQL Select 語句執(zhí)行順序

    一條 SQL 查詢語句結(jié)構(gòu)如下: 但真正的執(zhí)行步驟如下,執(zhí)行時,每個步驟都會產(chǎn)生一個虛擬表,該虛擬表被用作下一個步驟的輸入: 1. FROM 在這一步,無論后面跟那種聯(lián)接運算(LEFT JOIN、RIGHT JOIN等),都首先執(zhí)行交叉聯(lián)接(CROSS JOIN),計算笛卡爾積,生成虛擬表 VT-1 2. ON 根

    2024年02月05日
    瀏覽(31)
  • 【MySQL系列】- SELECT語句執(zhí)行順序

    【MySQL系列】- SELECT語句執(zhí)行順序

    2.1 執(zhí)行FROM操作 這一步需要做的是對FROM子句前后的兩張表進(jìn)行笛卡爾積操作,也稱作為交叉連接,生成虛擬表VT1。如果FROM子句前的表包含a行數(shù)據(jù),F(xiàn)ROM子句后的表中包含b行數(shù)據(jù),那么虛擬表VT1將包含a*b行數(shù)據(jù)。 2.2 應(yīng)用ON過濾器 SELECT查詢共有3個過濾流程,分別是ON、WHERE、

    2024年02月08日
    瀏覽(44)
  • Mysql的學(xué)習(xí)與鞏固:一條SQL查詢語句是如何執(zhí)行的?

    Mysql的學(xué)習(xí)與鞏固:一條SQL查詢語句是如何執(zhí)行的?

    我們經(jīng)常說,看一個事兒千萬不要直接陷入細(xì)節(jié)里,你應(yīng)該先鳥瞰其全貌,這樣能夠幫助你從高維度理解問題。同樣,對于MySQL的學(xué)習(xí)也是這樣。平時我們使用數(shù)據(jù)庫,看到的通常都是一個整體。比如,你有個最簡單的表,表里只有一個ID字段,在執(zhí)行下面這個查詢語句時:

    2023年04月13日
    瀏覽(97)
  • MYSQL實戰(zhàn)45講筆記--基礎(chǔ)架構(gòu):一條SQL查詢語句是如何執(zhí)行的?

    MYSQL實戰(zhàn)45講筆記--基礎(chǔ)架構(gòu):一條SQL查詢語句是如何執(zhí)行的?

    MySQL 可以分為 Server 層和存儲引擎層兩部分。 Server 層 :連接器、查詢緩存、分析器、優(yōu)化器、執(zhí)行器等,涵蓋 MySQL 的大多數(shù)核心服務(wù)功能,以及所有的內(nèi)置函數(shù)(如日期、時間、數(shù)學(xué)和加密函數(shù)等),所有跨存儲引擎的功能都在這一層實現(xiàn),比如存儲過程、觸發(fā)器、視圖等

    2024年02月07日
    瀏覽(23)
  • MySQL數(shù)據(jù)庫——MySQL SELECT:數(shù)據(jù)表查詢語句

    在?MySQL 中,可以使用 SELECT 語句來查詢數(shù)據(jù)。查詢數(shù)據(jù)是指從數(shù)據(jù)庫中根據(jù)需求,使用不同的查詢方式來獲取不同的數(shù)據(jù),是使用頻率最高、最重要的操作。 SELECT 的語法格式如下: 其中,各條子句的含義如下: {*|字段列名} 包含星號通配符的字段列表,表示所要查詢字段的

    2024年02月05日
    瀏覽(233)
  • MySQL中,SQL 查詢總是先執(zhí)行SELECT語句嗎?

    在使用 MySQL 進(jìn)行查詢時,我們通常會使用 SELECT 語句,但是 SELECT 語句是否總是最先被執(zhí)行呢?這是一個非常有趣的問題,本文將對此進(jìn)行探討。 在 MySQL 中,SQL 查詢通常包括以下幾個步驟: 語法解析 :MySQL 會對 SQL 查詢語句進(jìn)行語法解析,檢查語句是否符合 SQL 語法規(guī)范。

    2023年04月09日
    瀏覽(21)
  • 基本的SELECT語句——“MySQL數(shù)據(jù)庫”

    基本的SELECT語句——“MySQL數(shù)據(jù)庫”

    各位CSDN的uu們好呀,好久沒有更新小雅蘭的MySQL數(shù)據(jù)庫專欄啦,接下來一段時間,小雅蘭都會更新MySQL數(shù)據(jù)庫的知識,下面,讓我們進(jìn)入今天的主題吧——基本的SELECT語句!?。?SQL概述 SQL語言的規(guī)則與規(guī)范 基本的SELECT語句 顯示表結(jié)構(gòu) 過濾數(shù)據(jù) 1946 年,世界上第一臺電腦誕生

    2024年02月09日
    瀏覽(88)
  • Mysql數(shù)據(jù)庫(六):基本的SELECT語句

    Mysql數(shù)據(jù)庫(六):基本的SELECT語句

    本博主將用CSDN記錄軟件開發(fā)求學(xué)之路上親身所得與所學(xué)的心得與知識,有興趣的小伙伴可以關(guān)注博主!也許一個人獨行,可以走的很快,但是一群人結(jié)伴而行,才能走的更遠(yuǎn)! 語法: 選擇全部列: 一般情況下,除非需要使用表中所有的字段數(shù)據(jù),最好不要使用通配符‘ *

    2024年02月08日
    瀏覽(99)
  • Mysql數(shù)據(jù)庫:select from語句詳解

    ??The Begin??點點關(guān)注,收藏不迷路?? select from語句用于從數(shù)據(jù)庫中查詢數(shù)據(jù)。它由兩個組成:select 和from。 select 用于指定要查詢的列,from用于指定要查詢的表。 通過結(jié)合使用這兩個,我們可以從數(shù)據(jù)庫中選擇特定的列和行進(jìn)行查詢。 下面是se

    2024年02月03日
    瀏覽(93)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包