日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > 数据库 >内容正文

数据库

【MySQL原理解析】01. 一条SQL查询语句是如何执行的

發(fā)布時(shí)間:2023/12/10 数据库 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【MySQL原理解析】01. 一条SQL查询语句是如何执行的 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

這是【MySQL原理解析】的第一篇文章,MySQL我看了很多的書與教程,對(duì)其原理有一定的理解,一直想寫一系列的文章來(lái)把MySQL的原理給講清楚,一直沒有時(shí)間寫,今天算是個(gè)開頭吧。萬(wàn)事開頭難,咱們先破了這個(gè)開頭!

MySQL基本架構(gòu)

我們常說,看一件事不要直接陷入細(xì)節(jié),應(yīng)該先從整體框架與流程上把握住,先從最高的維度理解問題,然后再逐步深入各個(gè)模塊。學(xué)習(xí)MySQL也是一樣,在使用MySQL的過程中,我們最開始都是從一條簡(jiǎn)單的查詢語(yǔ)句開始。如在學(xué)生表student中按照學(xué)生的id來(lái)查學(xué)生的信息:

select * from student where id = 100;

在我們程序員眼里,這就是一條sql語(yǔ)句,執(zhí)行之后,返回一條結(jié)果。這看起來(lái)很簡(jiǎn)單的過程,實(shí)際在MySQL內(nèi)部,卻是一個(gè)非常復(fù)雜的過程。今天我們就來(lái)把這個(gè)過程拆解出來(lái)。
下面給出的是MySQL的基本架構(gòu)示意圖,從中可以看出SQL語(yǔ)句在MySQL的各個(gè)功能模塊的執(zhí)行過程。

MySQL的基本架構(gòu)可以分為兩大塊,一塊是Server層,一塊是存儲(chǔ)引擎層。

Server層包括連接器、查詢緩存、分析器、優(yōu)化器、執(zhí)行器等。涵蓋了MySQL大多數(shù)的核心服務(wù)功能、以及所有的內(nèi)置函數(shù),所有跨存儲(chǔ)引擎的功能都在這一層實(shí)現(xiàn),比如存儲(chǔ)過程、觸發(fā)器。視圖等。

存儲(chǔ)引擎層負(fù)責(zé)數(shù)據(jù)的存儲(chǔ)與提取。其架構(gòu)模式是插件式的,支持InnoDB、MyISAM、Memmory等多個(gè)存儲(chǔ)引擎。最常用的是InnoDB存儲(chǔ)引擎。所以我們的系列文章也主要是以InnoDB存儲(chǔ)引擎為主。

連接器

在客戶端執(zhí)行上面的查詢語(yǔ)句時(shí),客戶端首先會(huì)與服務(wù)端建立一個(gè)TCP連接,每個(gè)客戶端連接都會(huì)在服務(wù)端進(jìn)程中擁有一個(gè)線程。這個(gè)連接的查詢只會(huì)在這個(gè)單獨(dú)的線程中執(zhí)行,該線程只能輪流在某個(gè)CPU中運(yùn)行。服務(wù)器會(huì)負(fù)責(zé)緩存線程,因此不需要為每一個(gè)新建的連接創(chuàng)建或者銷毀線程。在連接的過程中還涉及到一些安全校驗(yàn)與權(quán)限校驗(yàn)等。

連接成功后,如果沒有后續(xù)的動(dòng)作,這個(gè)連接就處于空閑的狀態(tài),你可以使用 show processlist 命令來(lái)查看線程的各個(gè)狀態(tài)。客戶端如果長(zhǎng)時(shí)間沒有動(dòng)靜,連接器會(huì)自動(dòng)將它斷開。這個(gè)時(shí)間由參數(shù)wait_timeout控制,一般是8小時(shí)。如果在連接被斷開后,客戶端再次發(fā)送請(qǐng)求的話,就會(huì)收到一個(gè)錯(cuò)誤提醒:Lost connection to MySQL server during query。這時(shí)候如果還要繼續(xù)查詢,就要重新建立連接,然后再執(zhí)行請(qǐng)求。

在數(shù)據(jù)庫(kù)領(lǐng)域,長(zhǎng)連接是連接成功后,如果客戶端有請(qǐng)求,則一直使用同一個(gè)連接。短連接則是指每次執(zhí)行完很少的幾次查詢就斷開連接,下次查詢?cè)僦匦陆⒁粋€(gè)。

我們知道TCP建立連接的過程都是非常復(fù)雜的,所以應(yīng)該降低建立連接這個(gè)動(dòng)作,也就是盡量使用長(zhǎng)連接。但是全部使用長(zhǎng)連接后,有可能也會(huì)導(dǎo)致MySQL占用內(nèi)存特別快,這是因?yàn)镸ySQL在執(zhí)行的過程中,臨時(shí)使用的內(nèi)存都是管理在連接對(duì)象里的。這些臨時(shí)使用的內(nèi)存在斷開連接才會(huì)被釋放。所以如果長(zhǎng)連接積累下來(lái),可能導(dǎo)致占用內(nèi)存太大,被系統(tǒng)強(qiáng)行殺掉(OOM),異常重啟。

想要使用長(zhǎng)連接,并且還要解決這種OOM問題的話,可以考慮以下兩種方案。

  • 定期斷開長(zhǎng)連接。使用一段時(shí)間,或者程序里面判斷執(zhí)行一個(gè)占用很大內(nèi)存的查詢后,斷開連接,之后要查詢?cè)僦剡B。
  • 在比較新的MySQL版本中,可以在每次執(zhí)行一個(gè)比較大的操作后,執(zhí)行mysql_reset_connection操作來(lái)重新初始化連接資源。這個(gè)過程不需要重連和重新做權(quán)限校驗(yàn)等,但是會(huì)將連接恢復(fù)到剛剛創(chuàng)建完時(shí)的狀態(tài)。
  • 查詢緩存

    連接建立成功后,就可以進(jìn)行select查詢語(yǔ)句了。MySQL拿到一個(gè)查詢請(qǐng)求后,會(huì)先到查詢緩存看看之前是否有過一樣的查詢,如果有則直接返回結(jié)果。如果沒有,才會(huì)進(jìn)行后面的操作。

    我們可以看到,查詢緩存如果命中,就不會(huì)走后面的分析器、優(yōu)化器以及存儲(chǔ)引擎提取數(shù)據(jù)了。但是存儲(chǔ)引擎在最新的MySQL8.0版本中已經(jīng)不再支持查詢緩存的功能了。為什么呢?

    因?yàn)椴樵兙彺媸Х浅nl繁,只要有對(duì)一個(gè)表的更新操作,這個(gè)表上所的查詢緩存都會(huì)被清空。因此很可能你費(fèi)勁的把緩存建立起來(lái),還沒使用呢,就被一個(gè)更新全清空了。對(duì)于更新壓力大的數(shù)據(jù)庫(kù)來(lái)說,查詢緩存的命中率會(huì)非常低。

    分析器

    解析器說白了就是對(duì)你輸入的sql語(yǔ)句的解析,解析成MySQL這個(gè)服務(wù)端程序能夠識(shí)別的代碼。解析的過程中肯定會(huì)有判斷sql語(yǔ)句是否正確的語(yǔ)法解析的過程。如果你的語(yǔ)法不對(duì),肯定會(huì)報(bào)錯(cuò)。這個(gè)過程的原理涉及到詞法分析樹與語(yǔ)法分析樹,較為復(fù)雜,這里暫時(shí)不深究。

    優(yōu)化器

    經(jīng)過分析器解析出MySQL能夠識(shí)別出的代碼后,優(yōu)化器會(huì)對(duì)這部分查詢代碼做一系列的算法優(yōu)化,包括重寫查詢、決定表的讀取順序,以及選擇合適的索引等。用戶可以通過特殊的關(guān)鍵字提示(hint)優(yōu)化器,影響它的決策過程。也可以請(qǐng)求優(yōu)化器解釋(explain)優(yōu)化過程的各個(gè)因素,使用戶可以知道服務(wù)器是如何進(jìn)行優(yōu)化決策的。

    對(duì)于優(yōu)化器有哪些優(yōu)化方法來(lái)優(yōu)化查詢,在后面的章節(jié)我們會(huì)詳細(xì)說明。

    執(zhí)行器

    MySQL通過分析器知道了你要做什么,通過優(yōu)化器知道了該如何做,接下來(lái)就該真正的開始執(zhí)行了。

    在開始執(zhí)行的時(shí)候,MySQL會(huì)再次判斷本次查詢是否對(duì)要查詢的表有執(zhí)行查詢的權(quán)限,如果沒有會(huì)報(bào)錯(cuò)。如果有權(quán)限就打開表繼續(xù)執(zhí)行。打開表的時(shí)候,執(zhí)行器會(huì)根據(jù)這個(gè)表所使用的存儲(chǔ)引擎,選擇對(duì)應(yīng)的存儲(chǔ)引擎接口。

    小結(jié)

    本篇文章主要講解了MySQL的基本架構(gòu),MySQL的整體架構(gòu)還是非常復(fù)雜的,我們能夠?qū)ySQL的基本架構(gòu)搞懂就行。這次主要學(xué)會(huì)一條查詢語(yǔ)句,大致需要經(jīng)歷哪些流程,經(jīng)過了哪些模塊,每一個(gè)模塊的細(xì)化流程都相當(dāng)復(fù)雜,我們也不必把每一個(gè)模塊都搞懂。作為一名后端開發(fā)人員,將優(yōu)化器與存儲(chǔ)引擎層的相關(guān)原理搞懂就可以。

    在后面的章節(jié),我們會(huì)深入學(xué)習(xí)優(yōu)化器與存儲(chǔ)引擎相關(guān)原理!

    總結(jié)

    以上是生活随笔為你收集整理的【MySQL原理解析】01. 一条SQL查询语句是如何执行的的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。