主頁 > 資料庫 > 一條 SQL 陳述句在 MySQL 中如何執行的

一條 SQL 陳述句在 MySQL 中如何執行的

2020-11-20 14:07:25 資料庫

一 MySQL 基礎架構分析

1.1 MySQL 基本架構概覽

下圖是 MySQL 的一個簡要架構圖,從下圖你可以很清晰的看到用戶的 SQL 陳述句在 MySQL 內部是如何執行的,

先簡單介紹一下下圖涉及的一些組件的基本作用幫助大家理解這幅圖,在 1.2 節中會詳細介紹到這些組件的作用,

  • 連接器: 身份認證和權限相關(登錄 MySQL 的時候),
  • 查詢快取: 執行查詢陳述句的時候,會先查詢快取(MySQL 8.0 版本后移除,因為這個功能不太實用),
  • 分析器: 沒有命中快取的話,SQL 陳述句就會經過分析器,分析器說白了就是要先看你的 SQL 陳述句要干嘛,再檢查你的 SQL 陳述句語法是否正確,
  • 優化器: 按照 MySQL 認為最優的方案去執行,
  • 執行器: 執行陳述句,然后從存盤引擎回傳資料,

簡單來說 MySQL 主要分為 Server 層和存盤引擎層:

  • Server 層:主要包括連接器、查詢快取、分析器、優化器、執行器等,所有跨存盤引擎的功能都在這一層實作,比如存盤程序、觸發器、視圖,函式等,還有一個通用的日志模塊 binglog 日志模塊,
  • 存盤引擎: 主要負責資料的存盤和讀取,采用可以替換的插件式架構,支持 InnoDB、MyISAM、Memory 等多個存盤引擎,其中 InnoDB 引擎有自有的日志模塊 redolog 模塊,現在最常用的存盤引擎是 InnoDB,它從 MySQL 5.5.5 版本開始就被當做默認存盤引擎了,

1.2 Server 層基本組件介紹

1) 連接器

連接器主要和身份認證和權限相關的功能相關,就好比一個級別很高的門衛一樣,

主要負責用戶登錄資料庫,進行用戶的身份認證,包括校驗賬戶密碼,權限等操作,如果用戶賬戶密碼已通過,連接器會到權限表中查詢該用戶的所有權限,之后在這個連接里的權限邏輯判斷都是會依賴此時讀取到的權限資料,也就是說,后續只要這個連接不斷開,即時管理員修改了該用戶的權限,該用戶也是不受影響的,

2) 查詢快取(MySQL 8.0 版本后移除)

查詢快取主要用來快取我們所執行的 SELECT 陳述句以及該陳述句的結果集,

連接建立后,執行查詢陳述句的時候,會先查詢快取,MySQL 會先校驗這個 sql 是否執行過,以 Key-Value 的形式快取在記憶體中,Key 是查詢預計,Value 是結果集,如果快取 key 被命中,就會直接回傳給客戶端,如果沒有命中,就會執行后續的操作,完成后也會把結果快取起來,方便下一次呼叫,當然在真正執行快取查詢的時候還是會校驗用戶的權限,是否有該表的查詢條件,

MySQL 查詢不建議使用快取,因為查詢快取失效在實際業務場景中可能會非常頻繁,假如你對一個表更新的話,這個表上的所有的查詢快取都會被清空,對于不經常更新的資料來說,使用快取還是可以的,

所以,一般在大多數情況下我們都是不推薦去使用查詢快取的,

MySQL 8.0 版本后洗掉了快取的功能,官方也是認為該功能在實際的應用場景比較少,所以干脆直接刪掉了,

3) 分析器

MySQL 沒有命中快取,那么就會進入分析器,分析器主要是用來分析 SQL 陳述句是來干嘛的,分析器也會分為幾步:

第一步,詞法分析,一條 SQL 陳述句有多個字串組成,首先要提取關鍵字,比如 select,提出查詢的表,提出欄位名,提出查詢條件等等,做完這些操作后,就會進入第二步,

第二步,語法分析,主要就是判斷你輸入的 sql 是否正確,是否符合 MySQL 的語法,

完成這 2 步之后,MySQL 就準備開始執行了,但是如何執行,怎么執行是最好的結果呢?這個時候就需要優化器上場了,

4) 優化器

優化器的作用就是它認為的最優的執行方案去執行(有時候可能也不是最優,這篇文章涉及對這部分知識的深入講解),比如多個索引的時候該如何選擇索引,多表查詢的時候如何選擇關聯順序等,

可以說,經過了優化器之后可以說這個陳述句具體該如何執行就已經定下來,

5) 執行器

當選擇了執行方案后,MySQL 就準備開始執行了,首先執行前會校驗該用戶有沒有權限,如果沒有權限,就會回傳錯誤資訊,如果有權限,就會去呼叫引擎的介面,回傳介面執行的結果,

二 陳述句分析

2.1 查詢陳述句

說了以上這么多,那么究竟一條 sql 陳述句是如何執行的呢?其實我們的 sql 可以分為兩種,一種是查詢,一種是更新(增加,更新,洗掉),我們先分析下查詢陳述句,陳述句如下:

select * from tb_student  A where A.age='18' and A.name=' 張三 ';

結合上面的說明,我們分析下這個陳述句的執行流程:

  • 先檢查該陳述句是否有權限,如果沒有權限,直接回傳錯誤資訊,如果有權限,在 MySQL8.0 版本以前,會先查詢快取,以這條 sql 陳述句為 key 在記憶體中查詢是否有結果,如果有直接快取,如果沒有,執行下一步,

  • 通過分析器進行詞法分析,提取 sql 陳述句的關鍵元素,比如提取上面這個陳述句是查詢 select,提取需要查詢的表名為 tb_student,需要查詢所有的列,查詢條件是這個表的 id='1',然后判斷這個 sql 陳述句是否有語法錯誤,比如關鍵詞是否正確等等,如果檢查沒問題就執行下一步,

  • 接下來就是優化器進行確定執行方案,上面的 sql 陳述句,可以有兩種執行方案:

      a.先查詢學生表中姓名為“張三”的學生,然后判斷是否年齡是 18,
      b.先找出學生中年齡 18 歲的學生,然后再查詢姓名為“張三”的學生,
    

    那么優化器根據自己的優化演算法進行選擇執行效率最好的一個方案(優化器認為,有時候不一定最好),那么確認了執行計劃后就準備開始執行了,

  • 進行權限校驗,如果沒有權限就會回傳錯誤資訊,如果有權限就會呼叫資料庫引擎介面,回傳引擎的執行結果,

2.2 更新陳述句

以上就是一條查詢 sql 的執行流程,那么接下來我們看看一條更新陳述句如何執行的呢?sql 陳述句如下:

update tb_student A set A.age='19' where A.name=' 張三 ';

我們來給張三修改下年齡,在實際資料庫肯定不會設定年齡這個欄位的,不然要被技術負責人打的,其實條陳述句也基本上會沿著上一個查詢的流程走,只不過執行更新的時候肯定要記錄日志啦,這就會引入日志模塊了,MySQL 自帶的日志模塊式 binlog(歸檔日志) ,所有的存盤引擎都可以使用,我們常用的 InnoDB 引擎還自帶了一個日志模塊 redo log(重做日志),我們就以 InnoDB 模式下來探討這個陳述句的執行流程,流程如下:

  • 先查詢到張三這一條資料,如果有快取,也是會用到快取,
  • 然后拿到查詢的陳述句,把 age 改為 19,然后呼叫引擎 API 介面,寫入這一行資料,InnoDB 引擎把資料保存在記憶體中,同時記錄 redo log,此時 redo log 進入 prepare 狀態,然后告訴執行器,執行完成了,隨時可以提交,
  • 執行器收到通知后記錄 binlog,然后呼叫引擎介面,提交 redo log 為提交狀態,
  • 更新完成,

這里肯定有同學會問,為什么要用兩個日志模塊,用一個日志模塊不行嗎?

這是因為最開始 MySQL 并沒與 InnoDB 引擎( InnoDB 引擎是其他公司以插件形式插入 MySQL 的) ,MySQL 自帶的引擎是 MyISAM,但是我們知道 redo log 是 InnoDB 引擎特有的,其他存盤引擎都沒有,這就導致會沒有 crash-safe 的能力(crash-safe 的能力即使資料庫發生例外重啟,之前提交的記錄都不會丟失),binlog 日志只能用來歸檔,

并不是說只用一個日志模塊不可以,只是 InnoDB 引擎就是通過 redo log 來支持事務的,那么,又會有同學問,我用兩個日志模塊,但是不要這么復雜行不行,為什么 redo log 要引入 prepare 預提交狀態?這里我們用反證法來說明下為什么要這么做?

  • 先寫 redo log 直接提交,然后寫 binlog,假設寫完 redo log 后,機器掛了,binlog 日志沒有被寫入,那么機器重啟后,這臺機器會通過 redo log 恢復資料,但是這個時候 bingog 并沒有記錄該資料,后續進行機器備份的時候,就會丟失這一條資料,同時主從同步也會丟失這一條資料,
  • 先寫 binlog,然后寫 redo log,假設寫完了 binlog,機器例外重啟了,由于沒有 redo log,本機是無法恢復這一條記錄的,但是 binlog 又有記錄,那么和上面同樣的道理,就會產生資料不一致的情況,

如果采用 redo log 兩階段提交的方式就不一樣了,寫完 binglog 后,然后再提交 redo log 就會防止出現上述的問題,從而保證了資料的一致性,那么問題來了,有沒有一個極端的情況呢?假設 redo log 處于預提交狀態,binglog 也已經寫完了,這個時候發生了例外重啟會怎么樣呢? 這個就要依賴于 MySQL 的處理機制了,MySQL 的處理程序如下:

  • 判斷 redo log 是否完整,如果判斷是完整的,就立即提交,
  • 如果 redo log 只是預提交但不是 commit 狀態,這個時候就會去判斷 binlog 是否完整,如果完整就提交 redo log, 不完整就回滾事務,

這樣就解決了資料一致性的問題,

三 總結

  • MySQL 主要分為 Server 層和引擎層,Server 層主要包括連接器、查詢快取、分析器、優化器、執行器,同時還有一個日志模塊(binlog),這個日志模塊所有執行引擎都可以共用,redolog 只有 InnoDB 有,
  • 引擎層是插件式的,目前主要包括,MyISAM,InnoDB,Memory 等,
  • 查詢陳述句的執行流程如下:權限校驗(如果命中快取)---》查詢快取---》分析器---》優化器---》權限校驗---》執行器---》引擎
  • 更新陳述句執行流程如下:分析器----》權限校驗----》執行器---》引擎---redo log(prepare 狀態---》binlog---》redo log(commit狀態)

作者:Snailclimb
鏈接:一條 SQL 陳述句在 MySQL 中如何執行的
來源:github

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/225499.html

標籤:MySQL

上一篇:使用JdbcTemplate查詢PostgreSQL的所有表

下一篇:[MySQL] mysql 5.5和 5.6 timestamp default 默認值CURRENT_TIMESTAMP問題

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • GPU虛擬機創建時間深度優化

    **?桔妹導讀:**GPU虛擬機實體創建速度慢是公有云面臨的普遍問題,由于通常情況下創建虛擬機屬于低頻操作而未引起業界的重視,實際生產中還是存在對GPU實體創建時間有苛刻要求的業務場景。本文將介紹滴滴云在解決該問題時的思路、方法、并展示最終的優化成果。 從公有云服務商那里購買過虛擬主機的資深用戶,一 ......

    uj5u.com 2020-09-10 06:09:13 more
  • 可編程網卡芯片在滴滴云網路的應用實踐

    **?桔妹導讀:**隨著云規模不斷擴大以及業務層面對延遲、帶寬的要求越來越高,采用DPDK 加速網路報文處理的方式在橫向縱向擴展都出現了局限性。可編程芯片成為業界熱點。本文主要講述了可編程網卡芯片在滴滴云網路中的應用實踐,遇到的問題、帶來的收益以及開源社區貢獻。 #1. 資料中心面臨的問題 隨著滴滴 ......

    uj5u.com 2020-09-10 06:10:21 more
  • 滴滴資料通道服務演進之路

    **?桔妹導讀:**滴滴資料通道引擎承載著全公司的資料同步,為下游實時和離線場景提供了必不可少的源資料。隨著任務量的不斷增加,資料通道的整體架構也隨之發生改變。本文介紹了滴滴資料通道的發展歷程,遇到的問題以及今后的規劃。 #1. 背景 資料,對于任何一家互聯網公司來說都是非常重要的資產,公司的大資料 ......

    uj5u.com 2020-09-10 06:11:05 more
  • 滴滴AI Labs斬獲國際機器翻譯大賽中譯英方向世界第三

    **桔妹導讀:**深耕人工智能領域,致力于探索AI讓出行更美好的滴滴AI Labs再次斬獲國際大獎,這次獲獎的專案是什么呢?一起來看看詳細報道吧! 近日,由國際計算語言學協會ACL(The Association for Computational Linguistics)舉辦的世界最具影響力的機器 ......

    uj5u.com 2020-09-10 06:11:29 more
  • MPP (Massively Parallel Processing)大規模并行處理

    1、什么是mpp? MPP (Massively Parallel Processing),即大規模并行處理,在資料庫非共享集群中,每個節點都有獨立的磁盤存盤系統和記憶體系統,業務資料根據資料庫模型和應用特點劃分到各個節點上,每臺資料節點通過專用網路或者商業通用網路互相連接,彼此協同計算,作為整體提供 ......

    uj5u.com 2020-09-10 06:11:41 more
  • 滴滴資料倉庫指標體系建設實踐

    **桔妹導讀:**指標體系是什么?如何使用OSM模型和AARRR模型搭建指標體系?如何統一流程、規范化、工具化管理指標體系?本文會對建設的方法論結合滴滴資料指標體系建設實踐進行解答分析。 #1. 什么是指標體系 ##1.1 指標體系定義 指標體系是將零散單點的具有相互聯系的指標,系統化的組織起來,通 ......

    uj5u.com 2020-09-10 06:12:52 more
  • 單表千萬行資料庫 LIKE 搜索優化手記

    我們經常在資料庫中使用 LIKE 運算子來完成對資料的模糊搜索,LIKE 運算子用于在 WHERE 子句中搜索列中的指定模式。 如果需要查找客戶表中所有姓氏是“張”的資料,可以使用下面的 SQL 陳述句: SELECT * FROM Customer WHERE Name LIKE '張%' 如果需要 ......

    uj5u.com 2020-09-10 06:13:25 more
  • 滴滴Ceph分布式存盤系統優化之鎖優化

    **桔妹導讀:**Ceph是國際知名的開源分布式存盤系統,在工業界和學術界都有著重要的影響。Ceph的架構和演算法設計發表在國際系統領域頂級會議OSDI、SOSP、SC等上。Ceph社區得到Red Hat、SUSE、Intel等大公司的大力支持。Ceph是國際云計算領域應用最廣泛的開源分布式存盤系統, ......

    uj5u.com 2020-09-10 06:14:51 more
  • es~通過ElasticsearchTemplate進行聚合~嵌套聚合

    之前寫過《es~通過ElasticsearchTemplate進行聚合操作》的文章,這一次主要寫一個嵌套的聚合,例如先對sex集合,再對desc聚合,最后再對age求和,共三層嵌套。 Aggregations的部分特性類似于SQL語言中的group by,avg,sum等函式,Aggregation ......

    uj5u.com 2020-09-10 06:14:59 more
  • 爬蟲日志監控 -- Elastc Stack(ELK)部署

    傻瓜式部署,只需替換IP與用戶 導讀: 現ELK四大組件分別為:Elasticsearch(核心)、logstash(處理)、filebeat(采集)、kibana(可視化) 下載均在https://www.elastic.co/cn/downloads/下tar包,各組件版本最好一致,配合fdm會 ......

    uj5u.com 2020-09-10 06:15:05 more
最新发布
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:33:24 more
  • MySQL中binlog備份腳本分享

    關于MySQL的二進制日志(binlog),我們都知道二進制日志(binlog)非常重要,尤其當你需要point to point災難恢復的時侯,所以我們要對其進行備份。關于二進制日志(binlog)的備份,可以基于flush logs方式先切換binlog,然后拷貝&壓縮到到遠程服務器或本地服務器 ......

    uj5u.com 2023-04-20 08:28:06 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:27:27 more
  • 快取與資料庫雙寫一致性幾種策略分析

    本文將對幾種快取與資料庫保證資料一致性的使用方式進行分析。為保證高并發性能,以下分析場景不考慮執行的原子性及加鎖等強一致性要求的場景,僅追求最終一致性。 ......

    uj5u.com 2023-04-20 08:26:48 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:26:35 more
  • 云時代,MySQL到ClickHouse資料同步產品對比推薦

    ClickHouse 在執行分析查詢時的速度優勢很好的彌補了MySQL的不足,但是對于很多開發者和DBA來說,如何將MySQL穩定、高效、簡單的同步到 ClickHouse 卻很困難。本文對比了 NineData、MaterializeMySQL(ClickHouse自帶)、Bifrost 三款產品... ......

    uj5u.com 2023-04-20 08:26:29 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:25:13 more
  • Redis 報”OutOfDirectMemoryError“(堆外記憶體溢位)

    Redis 報錯“OutOfDirectMemoryError(堆外記憶體溢位) ”問題如下: 一、報錯資訊: 使用 Redis 的業務介面 ,產生 OutOfDirectMemoryError(堆外記憶體溢位),如圖: 格式化后的報錯資訊: { "timestamp": "2023-04-17 22: ......

    uj5u.com 2023-04-20 08:24:54 more
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:24:03 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:23:11 more