亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Mysql中select查詢語句的執(zhí)行方式

 更新時(shí)間:2025年06月29日 14:23:58   作者:找不到、了  
這篇文章主要介紹了Mysql中select查詢語句的執(zhí)行方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

MySQL 查詢語句可以分為 Server 層存儲(chǔ)引擎層。而 Server 層包括連接器、查詢緩存、解析器、預(yù)處理器、優(yōu)化器、執(zhí)行器等,

最后 Server 層再通過 API 接口形式調(diào)用對(duì)應(yīng)的存儲(chǔ)引擎層提供的接口來執(zhí)行增刪改查操作。

如下圖所示:

?

1、介紹

關(guān)于sql語句在執(zhí)行過程中,可能會(huì)涉及到以下的組件來進(jìn)行相互的調(diào)用。

1.1、組件介紹

組件及其作用,可參考:

1.2、Sql執(zhí)行順序

在 SQL 中,select語句的語法結(jié)構(gòu)看似是按照關(guān)鍵字書寫順序執(zhí)行的(如select ... from ... where ...),但實(shí)際執(zhí)行順序與語法順序并不完全一致。

如下圖所示:

注意:

在包含子查詢的 SQL 中,子查詢本身也是一個(gè)完整的select語句,其內(nèi)部仍然遵循上述執(zhí)行順序。外部查詢的執(zhí)行順序會(huì)以子查詢的最終結(jié)果為輸入繼續(xù)執(zhí)行。

為了更好地理解這個(gè)順序,我們可以從“數(shù)據(jù)流”的角度思考:

  • FROM:首先確定從哪個(gè)表或視圖中讀取數(shù)據(jù)。
  • WHERE:在獲取原始數(shù)據(jù)后,先進(jìn)行行級(jí)過濾,減少后續(xù)處理的數(shù)據(jù)量。
  • GROUP BY:將過濾后的數(shù)據(jù)按指定字段分組,為聚合操作做準(zhǔn)備。
  • HAVING:在分組后,進(jìn)一步過濾不滿足條件的組。
  • SELECT:確定最終返回的字段(包括常量、表達(dá)式、聚合函數(shù)等)。
  • ORDER BY:對(duì)最終結(jié)果進(jìn)行排序。
  • LIMIT:限制返回的記錄數(shù)量。

如下圖所示:

2、執(zhí)行流程

一個(gè)完整的執(zhí)行流程包括以下組件,連接器、緩存、解析器、優(yōu)化器、執(zhí)行器存儲(chǔ)引擎組成。

如下圖所示:

2.1. 連接與認(rèn)證

MySQL 服務(wù)端和客戶端的通信方式采用的是半雙工協(xié)議。

客戶端連接:客戶端通過協(xié)議(如 TCP/IP、Socket)與 MySQL 服務(wù)端建立連接。

認(rèn)證:服務(wù)端驗(yàn)證用戶身份(用戶名、密碼、權(quán)限)。如果驗(yàn)證失敗,連接終止。

權(quán)限檢查:確認(rèn)用戶是否有權(quán)限執(zhí)行當(dāng)前查詢(如 SELECT 權(quán)限)。

常見的通信方式主要可以分為三種:單工,半雙工,全雙工。

單工:

通信的時(shí)候,數(shù)據(jù)只能單向傳輸。比如說遙控器,我們只能用遙控器來控制電視機(jī),而不能用電視機(jī)來控制遙控器。

半雙工:

通信的時(shí)候,數(shù)據(jù)可以雙向傳輸,但是同一時(shí)間只能有一臺(tái)服務(wù)器在發(fā)送數(shù)據(jù),當(dāng) A 給 B 發(fā)送數(shù)據(jù)的時(shí)候,那么 B 就不能給 A
發(fā)送數(shù)據(jù),必須等到 A 發(fā)送結(jié)束之后,B 才能給 A 發(fā)送數(shù)據(jù)。比如說對(duì)講機(jī)。

全雙工:

通信的時(shí)候,數(shù)據(jù)可以雙向傳輸,并且可以同時(shí)傳輸。比如說我們打電話或者用通信軟件進(jìn)行語音和視頻通話等。

半雙工協(xié)議讓 MySQL 通信簡單快速,但是也在一定程度上限制了 MySQL 的性能,因?yàn)橐坏囊欢碎_始發(fā)送數(shù)據(jù),另一端必須要接收完全部數(shù)據(jù)才能做出響應(yīng)。

所以當(dāng)批量插入的時(shí)候盡量拆分成多次插入而不要一次插入太大數(shù)據(jù),同樣的查詢語句最好也帶上 limit 限制條數(shù),避免一次返回過多數(shù)據(jù)。

MySQL 單次傳輸數(shù)據(jù)包的大小可以通過變量 max_allowed_packet 控制,默認(rèn)大小為 64MB(5.7 版本默認(rèn)只有 4MB)。

執(zhí)行以下語句查看 max_allowed_packet 變量大?。?/p>

2.2. 查詢緩存

緩存命中檢查

如果開啟了查詢緩存(Query Cache),MySQL 會(huì)直接檢查是否有完全相同的查詢結(jié)果緩存。

命中:直接返回緩存結(jié)果。

未命中:進(jìn)入后續(xù)流程,并可能將結(jié)果寫入緩存(取決于配置)。

注意:MySQL 8.0 已移除查詢緩存功能。

移除原因:

因?yàn)?MySQL 的緩存使用條件非??量蹋峭ㄟ^一個(gè)大小寫敏感的哈希值去匹配的,這樣就是說一條查詢語句哪怕只是有一個(gè)空格不一致,都會(huì)導(dǎo)致無法使用緩存。而且一旦表里面有一行數(shù)據(jù)變動(dòng)了,那么關(guān)于這種表的所有緩存都會(huì)失效,所以一般我們都是不建議使用緩存。

在 MySQL 8.0 版本之前緩存也是默認(rèn)關(guān)閉的,可以通過變量 query_cache_type 進(jìn)行控制。

2.3. 語法解析(Parser)

詞法分析:將 SQL 語句拆分為 token(如關(guān)鍵字、標(biāo)識(shí)符、操作符等)。

語法分析:根據(jù) SQL 語法樹規(guī)則,檢查語句合法性(如SELECT * FROM table是否符合語法)。

生成抽象語法樹(AST):將 SQL 轉(zhuǎn)換為數(shù)據(jù)庫可理解的內(nèi)部結(jié)構(gòu)。

整個(gè)sql語句會(huì)被分割成:select,name,from,table,where,id,=,1這幾個(gè)字符。并且能識(shí)別出關(guān)鍵字和非關(guān)鍵字,然后根據(jù) sql 語句生成一個(gè)數(shù)據(jù)結(jié)構(gòu),也叫做解析樹。

如下圖所示:

2.4、執(zhí)行sql

如下圖所示:

1. 預(yù)處理(Preprocessor)

語義檢查

  • 檢查表、列是否存在。
  • 驗(yàn)證權(quán)限(如用戶是否有權(quán)限訪問指定的表或列)。
  • 替換別名、處理函數(shù)等。

生成邏輯查詢計(jì)劃

  • 將 AST 轉(zhuǎn)換為邏輯執(zhí)行計(jì)劃(如select a from t1 where b = 5)。

2. 查詢優(yōu)化器(Optimizer)

其目標(biāo)是生成最優(yōu)的執(zhí)行計(jì)劃即最小資源消耗、最快響應(yīng)時(shí)間)。

優(yōu)化步驟

選擇訪問路徑:決定是否使用索引(如全表掃描 vs 索引掃描)。如果有多個(gè)索引,選擇最合適的索引。

連接順序優(yōu)化(針對(duì)多表查詢):決定表的連接順序(如 A JOIN B JOIN C 的順序)。使用動(dòng)態(tài)規(guī)劃或代價(jià)模型(Cost Model)計(jì)算最優(yōu)順序。

其他優(yōu)化:優(yōu)化子查詢(如轉(zhuǎn)換為 JOIN)。優(yōu)化排序(ORDER BY)和分組(GROUP BY)。常量傳播、條件簡化等。

輸出執(zhí)行計(jì)劃:生成物理執(zhí)行計(jì)劃(如使用哪個(gè)索引、連接算法等)。

3. 執(zhí)行器(Executor)

執(zhí)行查詢計(jì)劃

  • 調(diào)用存儲(chǔ)引擎接口(如 InnoDB、MyISAM)獲取數(shù)據(jù)。
  • 根據(jù)執(zhí)行計(jì)劃逐層處理(如過濾、排序、分組)。

權(quán)限二次檢查

  • 確保用戶對(duì)訪問的數(shù)據(jù)有權(quán)限。

數(shù)據(jù)處理

  • 讀取數(shù)據(jù)行(通過全表掃描或索引掃描)。
  • 應(yīng)用 WHERE 條件過濾。
  • 對(duì)結(jié)果進(jìn)行排序、分組、聚合等操作。

2.5. 存儲(chǔ)引擎交互

存儲(chǔ)引擎接口

  • MySQL 通過統(tǒng)一的接口(Handler API)與存儲(chǔ)引擎交互。

InnoDB 的處理

  • 通過 B+ 樹索引定位數(shù)據(jù)。
  • 處理事務(wù)(如鎖機(jī)制、MVCC)。
  • 返回符合條件的記錄。

其他引擎

  • 如 MyISAM 的處理方式不同(無事務(wù)支持)。

2.6. 返回結(jié)果

結(jié)果集組裝

  • 將處理后的數(shù)據(jù)按用戶指定的格式(如 SELECT 字段)組裝。

分頁處理

  • 若涉及 LIMIT 或分頁,截取對(duì)應(yīng)的數(shù)據(jù)。

返回客戶端

  • 一次性返回(小結(jié)果集)。
  • 流式返回(大結(jié)果集,通過網(wǎng)絡(luò)分批次傳輸)。

MySQL 將查詢結(jié)果返回是一個(gè)增量的逐步返回過程。

當(dāng)處理完所有查詢邏輯并開始執(zhí)行查詢并且生成第一條結(jié)果數(shù)據(jù)的時(shí)候,MySQL 就可以開始逐步的向客戶端傳輸數(shù)據(jù)了。這么做的好處是服務(wù)端無需存儲(chǔ)太多結(jié)果,從而減少內(nèi)存消耗。

3、示例流程(SELECT 查詢)

SELECT * FROM users WHERE id = 1;為例:

  • 客戶端連接數(shù)據(jù)庫。
  • 檢查查詢緩存(未命中)。
  • 解析 SQL 語法,生成 AST。
  • 預(yù)處理:檢查users表和id列是否存在。
  • 優(yōu)化器選擇id索引進(jìn)行查找。
  • 執(zhí)行器調(diào)用 InnoDB 引擎,通過索引定位到id=1的記錄。
  • 返回結(jié)果給客戶端。

4、常見問題與優(yōu)化

  • 慢查詢:檢查執(zhí)行計(jì)劃(使用EXPLAIN),優(yōu)化索引或調(diào)整查詢邏輯。
  • 全表掃描:添加合適的索引或優(yōu)化查詢條件。
  • JOIN 性能:調(diào)整連接順序或使用索引。
  • 緩存失效:頻繁更新的表可能導(dǎo)致緩存命中率低(MySQL 8.0 后不再依賴此)。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • mysql如何根據(jù)漢字首字母排序

    mysql如何根據(jù)漢字首字母排序

    這篇文章主要介紹了mysql根據(jù)漢字首字母排序sql語句,需要的朋友可以參考下
    2014-03-03
  • 淺析MySQL顯式類型轉(zhuǎn)換

    淺析MySQL顯式類型轉(zhuǎn)換

    這篇文章主要介紹了MySQL顯式類型轉(zhuǎn)換的基礎(chǔ)知識(shí),通過實(shí)例給出了分析結(jié)果,一起學(xué)習(xí)下吧。
    2017-12-12
  • mysql記錄根據(jù)日期字段倒序輸出

    mysql記錄根據(jù)日期字段倒序輸出

    這篇文章主要介紹了mysql記錄根據(jù)日期字段倒序輸出 的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07
  • mysql解決遠(yuǎn)程不能訪問的二種方法

    mysql解決遠(yuǎn)程不能訪問的二種方法

    mysql解決遠(yuǎn)程不能訪問的二種方法,需要的朋友可以參考一下
    2013-04-04
  • 詳解java調(diào)用ffmpeg轉(zhuǎn)換視頻格式為flv

    詳解java調(diào)用ffmpeg轉(zhuǎn)換視頻格式為flv

    這篇文章主要介紹了 詳解java調(diào)用ffmpeg轉(zhuǎn)換視頻格式為flv的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下
    2017-09-09
  • MySQL中ALTER?LOGFILE?GROUP?語句的具體使用

    MySQL中ALTER?LOGFILE?GROUP?語句的具體使用

    ALTER LOGFILE GROUP語句用于修改重做日志組的配置,本文主要介紹了MySQL中ALTER?LOGFILE?GROUP?語句的具體使用,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-07-07
  • MySQL表的增刪改查基礎(chǔ)教程

    MySQL表的增刪改查基礎(chǔ)教程

    這篇文章主要給大家介紹了關(guān)于MySQL表的增刪改查的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • MySQL事務(wù)及Spring隔離級(jí)別實(shí)現(xiàn)原理詳解

    MySQL事務(wù)及Spring隔離級(jí)別實(shí)現(xiàn)原理詳解

    這篇文章主要介紹了MySQL事務(wù)及Spring隔離級(jí)別實(shí)現(xiàn)原理詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • MySQL筆記之別名的使用

    MySQL筆記之別名的使用

    在查詢時(shí),可以為表和字段取一個(gè)別名。這個(gè)別名可以代替其指定的表和字段
    2013-05-05
  • SQL中CONVERT轉(zhuǎn)換函數(shù)的簡單使用方法

    SQL中CONVERT轉(zhuǎn)換函數(shù)的簡單使用方法

    CONVERT()函數(shù)對(duì)于簡單類型轉(zhuǎn)換,CONVERT()函數(shù)和CAST()函數(shù)的功能相同,只是語法不同,下面這篇文章主要給大家介紹了關(guān)于SQL中CONVERT轉(zhuǎn)換函數(shù)的簡單使用方法,需要的朋友可以參考下
    2024-01-01

最新評(píng)論