濮阳杆衣贸易有限公司

主頁(yè) > 知識(shí)庫(kù) > 詳解MySQL 查詢(xún)語(yǔ)句的執(zhí)行過(guò)程

詳解MySQL 查詢(xún)語(yǔ)句的執(zhí)行過(guò)程

熱門(mén)標(biāo)簽:怎樣在地圖標(biāo)注銷(xiāo)售區(qū)域 啥是企業(yè)400電話辦理 武漢網(wǎng)絡(luò)外呼系統(tǒng)服務(wù)商 電話外呼系統(tǒng)改號(hào) 南昌三維地圖標(biāo)注 外呼系統(tǒng)打電話上限是多少 百應(yīng)電話機(jī)器人優(yōu)勢(shì) 曲靖移動(dòng)外呼系統(tǒng)公司 地圖標(biāo)注費(fèi)用是多少

首先先簡(jiǎn)單的將一個(gè)查詢(xún)語(yǔ)句背后MySQL做了什么捋一捋:

  • 客戶(hù)端發(fā)送一條查詢(xún)給服務(wù)器。
  • 服務(wù)器先檢查查詢(xún)緩存,如果命中了緩存,則立刻返回存儲(chǔ)在緩存中的結(jié)果。否則進(jìn)入下一個(gè)階段。
  • 服務(wù)器端進(jìn)行SQL解析,預(yù)處理,再由優(yōu)化器生成對(duì)應(yīng)的執(zhí)行計(jì)劃。
  • MySQL根據(jù)優(yōu)化器生成的執(zhí)行計(jì)劃,調(diào)用存儲(chǔ)引擎的API來(lái)執(zhí)行查詢(xún)。
  • 將結(jié)果返回給客戶(hù)端。

接著我們就將這個(gè)過(guò)程中的這些步驟詳細(xì)的進(jìn)行展開(kāi)。

1.客戶(hù)端和服務(wù)器端之間的通信方式

客戶(hù)端和服務(wù)器之間的通信是一種半雙工的通信,即在同一時(shí)刻,只能有一方向另一方發(fā)送數(shù)據(jù)。所以客戶(hù)端在發(fā)送完查詢(xún)請(qǐng)求之后,所能做的就是等待服務(wù)器將查詢(xún)的結(jié)果返回,并且需要一直地等到返回的數(shù)據(jù)全部接收完畢后才能進(jìn)行下一步的操作,而不可以在服務(wù)器發(fā)送的過(guò)程中中斷發(fā)送或者斷開(kāi)連接。

2.查詢(xún)緩存

在解析一個(gè)查詢(xún)語(yǔ)句之前,如果查詢(xún)緩存是打開(kāi)著的,那么MySQL會(huì)優(yōu)先檢查這個(gè)查詢(xún)是否命中查詢(xún)緩存中的數(shù)據(jù)。這個(gè)檢查是通過(guò)一個(gè)對(duì)大小寫(xiě)敏感的哈希表來(lái)實(shí)現(xiàn)的。在查詢(xún)命中緩存的情況下,直接從緩存中拿到結(jié)果并返回給客戶(hù)端。MySQL不會(huì)再執(zhí)行下面的操作,即查詢(xún)語(yǔ)句不會(huì)被解析,不會(huì)生成執(zhí)行計(jì)劃,不會(huì)被執(zhí)行。

3.查詢(xún)優(yōu)化處理

這個(gè)環(huán)節(jié)可能是整個(gè)查詢(xún)執(zhí)行過(guò)程中最為復(fù)雜的一個(gè)環(huán)節(jié),可以分為解析SQL,預(yù)處理和優(yōu)化SQL執(zhí)行計(jì)劃三個(gè)步驟。

(1)語(yǔ)法解析器和預(yù)處理
這個(gè)過(guò)程就是對(duì)我們傳入的SQL語(yǔ)句的語(yǔ)法進(jìn)行檢查,以及驗(yàn)證查詢(xún)的權(quán)限。炳輝生成一棵“解析樹(shù)”。

(2)查詢(xún)優(yōu)化器
在進(jìn)入到這一步時(shí),證明我們的語(yǔ)句語(yǔ)法層面已經(jīng)沒(méi)有問(wèn)題了。一條查詢(xún)可以有很多種執(zhí)行計(jì)劃都能返回正確的結(jié)果,這個(gè)環(huán)節(jié)就是來(lái)選取最優(yōu)的執(zhí)行計(jì)劃的。
MySQL的最優(yōu)執(zhí)行計(jì)劃是基于成本的。MySQL會(huì)為每個(gè)操作設(shè)定一個(gè)成本(如執(zhí)行一次where比較),并從所有的執(zhí)行計(jì)劃中選擇“成本”最少的。
我們可以使用下列語(yǔ)句查看上一個(gè)查詢(xún)操作的成本:

mysql> SHOW STATUS LIKE 'last_query_cost';

MySQL會(huì)返回一個(gè)執(zhí)行的成本數(shù)據(jù):

+-----------------+----------+
| Variable_name  | Value  |
+-----------------+----------+
| Last_query_cost | 0.549000 |
+-----------------+----------+

但值得注意的是,這里的“成本”最小并不等于查詢(xún)的速度最快。即以“成本”來(lái)判斷查詢(xún)語(yǔ)句的優(yōu)劣有時(shí)候是不可靠的。

優(yōu)化器的優(yōu)化策略可以大致地分為兩種:靜態(tài)優(yōu)化和動(dòng)態(tài)優(yōu)化。

靜態(tài)優(yōu)化是直接對(duì)之前生成的解析樹(shù)進(jìn)行分析,例如可以通過(guò)一些代數(shù)變換將where條件轉(zhuǎn)化為另一種等價(jià)形式。靜態(tài)優(yōu)化在第一次完成后就一直生效,即使使用不同的參數(shù)重復(fù)執(zhí)行查詢(xún)也不會(huì)發(fā)生變化,可以認(rèn)為是一種“編譯(預(yù)處理)時(shí)優(yōu)化”。

動(dòng)態(tài)優(yōu)化和查詢(xún)的上下文相關(guān),需要在每一次查詢(xún)的時(shí)候重新評(píng)估,可以認(rèn)為是一種“運(yùn)行時(shí)優(yōu)化”。

下面是一些MySQL能夠處理的優(yōu)化類(lèi)型:

  • 重新定義關(guān)聯(lián)表的順序

有時(shí)候我們所給的查詢(xún)語(yǔ)句關(guān)聯(lián)表的順序可能對(duì)于查詢(xún)來(lái)說(shuō)效率并不是最優(yōu)的,這時(shí)候MySQL可以自動(dòng)幫我們將關(guān)聯(lián)表的順序進(jìn)行調(diào)整提高效率。

  • 將外連接轉(zhuǎn)化為內(nèi)連接

并不是所有的OUT JOIN語(yǔ)句都必須以外連接的方式執(zhí)行。MySQL能夠識(shí)別這一點(diǎn)并重寫(xiě)查詢(xún),讓其可以調(diào)整關(guān)聯(lián)順序。

  • 使用等價(jià)變換規(guī)則

使用一些等價(jià)的語(yǔ)句來(lái)減少比較的次數(shù),移除一些恒成立和不恒成立的條件。例如,(5=5 AND a>5)會(huì)被改寫(xiě)為a>5;如果有(a5 AND b=c AND a=5。

  • 優(yōu)化COUNT()、MIN()和MAX()

索引和列是否為空可以幫助優(yōu)化這一類(lèi)表達(dá)式。例如查找最小值的時(shí)候就可以借助索引直接查找最左端的記錄,這樣就不用進(jìn)行整個(gè)表的查詢(xún),而是以一個(gè)常數(shù)進(jìn)行取代。

  • 覆蓋索引掃描

當(dāng)索引中的列包含所有查詢(xún)中需要使用的列的時(shí)候,MySQL就會(huì)使用索引返回所需要的數(shù)據(jù),而無(wú)須查詢(xún)對(duì)應(yīng)的數(shù)據(jù)行。

  • 提前終止查詢(xún)

在發(fā)現(xiàn)查詢(xún)已經(jīng)能滿足需求的時(shí)候,MySQL總能立刻終止查詢(xún)。一個(gè)典型的例子就是當(dāng)使用了LIMIT子句的時(shí)候。

至此,MySQL服務(wù)器層已經(jīng)根據(jù)所給的查詢(xún)語(yǔ)句給出了一個(gè)最優(yōu)的執(zhí)行計(jì)劃。但是我們需要知道的是,我們到目前為止所進(jìn)行的一些列的操作都是在服務(wù)器層進(jìn)行的,而這一層中并不是數(shù)據(jù)存儲(chǔ)的地方。因此接下來(lái)我們需要拿著我們的最優(yōu)執(zhí)行計(jì)劃去到實(shí)際的存儲(chǔ)引擎中進(jìn)行查找。因此就引出了我們的下一步操作:向存儲(chǔ)引擎獲取相應(yīng)的統(tǒng)計(jì)信息。

4.查詢(xún)執(zhí)行引擎

相對(duì)于查詢(xún)優(yōu)化階段,查詢(xún)執(zhí)行階段并不是那么復(fù)雜。MySQL只是簡(jiǎn)單地根據(jù)執(zhí)行計(jì)劃給出的指令逐步執(zhí)行。

5.返回結(jié)果給客戶(hù)端

查詢(xún)執(zhí)行的最后一個(gè)階段是將結(jié)果返回給客戶(hù)端,即使查詢(xún)不需要返回結(jié)果集給客戶(hù)端,MySQL仍然會(huì)返回這個(gè)查詢(xún)的一些信息,例如查詢(xún)影響的行數(shù)。
如果查詢(xún)可以被緩存,這個(gè)階段MySQL會(huì)講查詢(xún)的結(jié)果放到查詢(xún)緩存中。
返回結(jié)果的過(guò)程是一個(gè)逐步增量的過(guò)程。即當(dāng)拿到第一個(gè)結(jié)果的時(shí)候就開(kāi)始向客戶(hù)端返回了。這樣做的好處是不會(huì)一次性返回全部數(shù)據(jù)導(dǎo)致占用內(nèi)存過(guò)多,而且客戶(hù)端也能在第一時(shí)間拿到結(jié)果。結(jié)果集中的每一行都會(huì)以一個(gè)滿足MySQL客戶(hù)端/服務(wù)器通信協(xié)議的封包發(fā)送,再通過(guò)TCP協(xié)議進(jìn)行傳輸,在TCP傳輸?shù)倪^(guò)程中,可能對(duì)封包進(jìn)行緩存后再批量發(fā)傳輸。

以上就是詳解MySQL 查詢(xún)語(yǔ)句的執(zhí)行過(guò)程的詳細(xì)內(nèi)容,更多關(guān)于MySQL 查詢(xún)語(yǔ)句的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

您可能感興趣的文章:
  • 一篇文章弄懂MySQL查詢(xún)語(yǔ)句的執(zhí)行過(guò)程
  • Python使用sql語(yǔ)句對(duì)mysql數(shù)據(jù)庫(kù)多條件模糊查詢(xún)的思路詳解
  • mysql查詢(xún)的控制語(yǔ)句圖文詳解
  • Mysql將查詢(xún)結(jié)果集轉(zhuǎn)換為JSON數(shù)據(jù)的實(shí)例代碼
  • 使用Visual Studio Code連接MySql數(shù)據(jù)庫(kù)并進(jìn)行查詢(xún)
  • MySQL查詢(xún)優(yōu)化之查詢(xún)慢原因和解決技巧
  • mysql聚合統(tǒng)計(jì)數(shù)據(jù)查詢(xún)緩慢的優(yōu)化方法
  • MySQL多表查詢(xún)的具體實(shí)例
  • mysql從一張表查詢(xún)批量數(shù)據(jù)并插入到另一表中的完整實(shí)例
  • 分析mysql中一條SQL查詢(xún)語(yǔ)句是如何執(zhí)行的

標(biāo)簽:甘南 吉林 荊州 錦州 隨州 滄州 資陽(yáng) 黑河

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《詳解MySQL 查詢(xún)語(yǔ)句的執(zhí)行過(guò)程》,本文關(guān)鍵詞  詳解,MySQL,查詢(xún),語(yǔ)句,的,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《詳解MySQL 查詢(xún)語(yǔ)句的執(zhí)行過(guò)程》相關(guān)的同類(lèi)信息!
  • 本頁(yè)收集關(guān)于詳解MySQL 查詢(xún)語(yǔ)句的執(zhí)行過(guò)程的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    永顺县| 潜山县| 岳阳市| 额济纳旗| 大关县| 承德市| 泾川县| 泽普县| 定远县| 固镇县| 肇州县| 祁门县| 新晃| 泗水县| 库伦旗| 万山特区| 静乐县| 东阿县| 岑溪市| 冕宁县| 新平| 锡林郭勒盟| 绥宁县| 临桂县| 广安市| 海原县| 奉节县| 松桃| 汝州市| 齐河县| 肥乡县| 铜川市| 象山县| 泌阳县| 昌平区| 通城县| 双江| 潜山县| 茶陵县| 灵武市| 连云港市|