成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

SQL語句在MySQL中是如何被執行的?

數據庫 MySQL
相信大家用了這么久的MySQL,一定很好奇自己寫的SQL是如何執行并返回結果的,今天我們就來一層一層剝開Mysql這顆洋蔥。

前言

相信大家用了這么久的MySQL,一定很好奇自己寫的SQL是如何執行并返回結果的,今天我們就來一層一層剝開MySQL這顆洋蔥。

首先我們通過一張圖來了解下整個過程,然后再開始一步一步解析。

第一步:客戶端發送SQL語句到MySQL服務端

假如項目中用到了Mybatis來操作數據庫,那么Mybatis就會通過JDBC來連接數據庫,并發送語句給數據庫,因為一般運行Web后臺服務的機器和MySQL服務都是物理上隔開的,是一個分布式架構,所以需要通過網絡來訪問,JDBC采用TCP連接的方式與MySQL服務端進行通信,通信的內容包括發送語句、接收執行結果等。雖然TCP是全雙工的,但是Mysql的TCP是半雙工的,這意味著同一時刻要么客戶端在發送數據,要么服務端在發送數據。

第二步:驗證連接合法性

JDBC與數據庫建立的連接的時候,會要求輸入用戶名和密碼,Mysql需要驗證用戶名是否存在,密碼是否正確。驗證通過后,再根據mysql.user表中的host字段來驗證客戶端IP是否是允許的IP,這個host字段相當于一個白名單。

前面的合法性都通過后,JDBC才會發送實際的SQL語句給MySQL服務端。

第三步:查詢緩存

像上面這種SELECT語句,MySQL服務端收到這個SQL時,如果開啟了查詢緩存,就會根據SQL語句在查詢緩存中查找,查找成功就直接返回查詢緩存中的結果給客戶端,而不會執行下面這些操作。

請注意,這里的查找方式是根據SQL語句進行hash運算,只要SQL中有一個字節不同都不會命中緩存。

第四步:語法解析和預處理

當查詢緩存沒有命中時,才會開始進行語法解析和預處理。語法解析就像一個編譯程序一樣,根據語句生成語法樹,并檢查語法樹中的關鍵字是否正確,順序是否正確,引號是否前后匹配等。

經過語法解析后,預處理就會檢查sql中的表、列是否存在,列名是否有歧義等,同時預處理還會對SQL進行權限認證,比如該用戶是否有SELECT權限、INSERT權限..., 是否有對應數據庫的權限、表的權限等等。

第五步:查詢優化

查詢優化主要分為兩部分,一是靜態優化二是動態優化。靜態優化可以把語句中一些where條件進行等價交換,比如:WHERE 1=1 AND a > 2將被替換為WHERE a > 2;靜態優化不依賴sql語句的具體值,就像Java靜態編譯器的語法糖一樣。

動態優化:因為動態優化以頁為最小單元來評估成本,所以需要分析SQL語句所對應的表的索引頁或者數據頁的數量,以此來確定是走索引還是全表掃描。這些信息都是通過存儲引擎來獲得的,所以如果存儲引擎給出的結果不精確,那么查詢優化的執行計劃可能就不是最優的。

因為一條sql可以選擇的執行方式有很多種,比如一張表里有多個索引,SQL語句涉及多個表的連接查詢,那么得到上述信息后,就需要評估使用哪些索引、哪個表關聯的順序是最優的,并以此來生成一條執行計劃。這部分也是Mysql服務層最復雜的地方,因為需要考量的因素有很多,這里筆者只是列出了一小部分。

第六步:調用存儲引擎執行

其實在MySQL中,真正決定怎么存儲數據和查詢數據的組件是存儲引擎。所以在第五步中得到了執行計劃后,MySQL會調用表所對應的存儲引擎的API,來執行真正的查詢。Mysql定義了一系列存儲引擎接口,來讓編寫存儲引擎的人來實現,所以只要符合接口定義的存儲引擎都是可以放入MySQL中去使用的。其中使用最廣泛的引擎莫過于InnoDB,InnoDB是一個支持事務、支持崩潰快速恢復的高性能存儲引擎。

Mysql服務層和存儲引擎層最大的區別是:服務層實現了一些不依賴于具體存儲引擎的通用操作,比如上面的連接驗證、SQL驗證這些。而存儲引擎則完成具體的查詢存儲操作,所以好的存儲引擎是Mysql的關鍵。

第七步:將結果返回給客戶端

容易想到的一種方式是MySQL服務端先把查詢結果緩存到內存中,然后再一次性發送給客戶端,可實際上不是這樣的。實際是拿到符合條件的第一條數據就返回給客戶端,這是一個增量過程。這樣做的原因,是可以緩解服務端的內存壓力。

如果開啟了查詢緩存,并且語句是UPDATE、DELETE、INSERT之類的操作,那么這個時候也會更新查詢緩存。

總結

在整個過程中,最復雜的部分是第五步的查詢優化和第六步中具體的存儲引擎,實現細節是造就了MySQL長盛不衰的原因。如果想要優化MySQL的性能,有幾步可以優化:

客戶端使用連接池,這樣可以讓連接復用,因為MySQL每接收一個連接都要用一個線程去處理,和其他Web服務器的連接池解決的問題一樣,這里也可以解決。

查詢緩存雖然在查詢時可以避免很多后續操作的成本,但是維護它的成本也挺高的,因為每次UPDATE、DELETE、INSERT都需要互斥地更新對應表的查詢緩存,這會成為MySQL的可擴展性瓶頸。根據阿姆達爾定律,決定一個系統能否水平擴展的是程序串行的部分。在MySQL8.0以上版本中,默認禁用了查詢緩存。所以除非你能確定查詢緩存確實對吞吐量有幫助,否則禁用查詢緩存是個好建議。

默認情況下,客戶端在第七步的接收過程中,其實是在自己的內存里緩存了全部結果之后,才會解除阻塞,這些會創建很多對象,當并發增高時,可能會引起JVM的OOM。所以這里可以改為每次只接收部分數據,處理完后再接收部分。但這里服務端對于資源都是持有狀態,所以是一個空間和時間上的權衡。

如果有必要,你可以干涉第五步的查詢優化過程,MySQL提供一些hint語句,比如強制走規定的關聯表順序或者強制使用某些索引。但是大多數情況下,請不要以為自己比查詢優化器更聰明,使用推薦的方案可能更好。

設計一個好的索引對于查詢的性能影響非常之大,所以對于使用關系型數據庫來說,索引設計是非常重要的一環。


責任編輯:華軒 來源: 今日頭條
相關推薦

2015-11-12 09:17:30

Java Main執行

2024-12-17 06:20:00

MySQLSQL語句數據庫

2022-07-28 09:13:30

MySQL數據庫

2024-12-26 08:16:26

2013-10-29 16:27:23

MySQLSQL語句

2022-02-11 14:43:53

SQL語句C/S架構

2010-09-06 13:41:42

sql server語句

2010-11-04 09:43:46

LINQ to SQL

2020-12-09 09:33:16

編程語言C語言匯編語言

2023-12-27 09:32:47

SQL語句數據

2025-02-19 10:18:29

2010-09-06 13:17:19

SQL Server語句

2021-06-07 08:37:03

SQL 查詢語句

2022-11-23 08:04:05

架構

2010-09-03 14:47:50

SQLSELECT語句

2018-07-17 14:25:02

SQL解析美團點評MySQL

2024-09-14 14:18:43

2023-11-30 15:37:37

MySQL數據庫

2010-09-25 14:59:54

SQL語句

2022-09-01 16:42:47

MySQL數據庫架構
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产成人精品一区二区三区在线 | www.久久久.com | 天堂在线中文字幕 | 成人在线播放网址 | 国产成人精品久久久 | 草樱av| 日韩免费av | 天堂在线中文 | 欧美日韩亚 | 国产在线观看一区二区三区 | 综合久久99 | 国产成人一区二 | 国产免费一区二区 | 青青草原综合久久大伊人精品 | 色精品视频 | 欧美视频网 | 天天躁日日躁aaaa视频 | 免费的av网站 | 亚洲国产乱码 | 在线一区二区三区 | 欧美在线视频一区二区 | 中文字幕一区二区不卡 | 精品一二区 | 黄色亚洲 | 在线观看国产网站 | 国产极品车模吞精高潮呻吟 | 精品国产欧美一区二区 | 国产精品视频二区三区 | 成人h视频 | 国产乱码精品一区二区三区五月婷 | 一级欧美黄色片 | 欧美综合久久久 | 国产精品美女久久久久久久网站 | 欧美一区二区三区大片 | 久久免费视频1 | 国产97在线 | 日韩 | 亚洲图片视频一区 | www.国产一区| 亚洲播放 | 91看片视频 | 亚洲一区二区三区视频在线 |