偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

MySQL系列之執(zhí)行SQL 語句時(shí)發(fā)生了什么?

數(shù)據(jù)庫(kù) MySQL
MySQL是一個(gè)客戶端、服務(wù)端的架構(gòu)。我們平時(shí)使用的大部分程序app其實(shí)是由兩部分組成的,一部分是客戶端程序,一部分是服務(wù)器程序。

[[408201]]

前言

當(dāng)我們用 navicat、mysql workbench 等mysql 的客戶端執(zhí)行一條sql語句后,我們就能得到相應(yīng)的結(jié)果。例如:

那么這個(gè)過程發(fā)生了什么呢?

執(zhí)行一條sql 就是一次Rpc的調(diào)用

mysql 是一個(gè)客戶端、服務(wù)端的架構(gòu)。我們平時(shí)使用的大部分程序app其實(shí)是由兩部分組成的,一部分是客戶端程序,一部分是服務(wù)器程序。

以我們常用的微信、qq 為例。我們手機(jī)里面裝的客戶端,機(jī)房的服務(wù)器中運(yùn)行著server端。我們平時(shí)發(fā)信息都是其實(shí)都是用客戶端和服務(wù)端打交道。比如你和你女朋友發(fā)信息的過程:

  1. 消息被客戶端包裝了一下,添加了發(fā)送者和接收者信息,然后從你的微信客戶端傳送給微信服務(wù)器;
  2. 微信服務(wù)器從消息里獲取到它的發(fā)送者和接收者,根據(jù)消息的接收者信息把這條消息送達(dá)到你女朋友的微信客戶端,你女朋友的微信客戶端里就顯示出你給他發(fā)了一條消息。

mysql的使用過程跟這個(gè)是一樣的,它的服務(wù)器程序直接和我們存儲(chǔ)的數(shù)據(jù)打交道,然后可以有好多客戶端程序連接到這個(gè)服務(wù)器程序,發(fā)送增刪改查的請(qǐng)求,然后服務(wù)器就響應(yīng)這些請(qǐng)求,從而操作它維護(hù)的數(shù)據(jù)。

主要流程如下:

所以,一條sql的執(zhí)行,就是一次rpc的調(diào)用。后面有時(shí)間也會(huì)分享RPC 相關(guān)的東西,一起交流學(xué)習(xí)!

服務(wù)器怎么處理客戶端請(qǐng)求

不管我們用了哪種客戶端和服務(wù)器進(jìn)程是采用哪種方式進(jìn)行通信,最后實(shí)現(xiàn)的效果都是:客戶端進(jìn)程向服務(wù)器進(jìn)程發(fā)送一段文本(MySQL語句),服務(wù)器進(jìn)程處理后再向客戶端進(jìn)程發(fā)送一段文本(處理結(jié)果)。主要過程如下:

從圖中我們可以看出,服務(wù)器程序處理來自客戶端的查詢請(qǐng)求大致需要經(jīng)過三個(gè)部分,分別是 連接管理、解析優(yōu)化與執(zhí)行、存儲(chǔ)引擎三個(gè)部分。其中連接管理、解析優(yōu)化與執(zhí)行常常被分為mysql的 server 層。

連接管理

客戶端進(jìn)程可以采用TCP/IP、命名管道或共享內(nèi)存、Unix域套接字這幾種方式之一來與服務(wù)器進(jìn)程建立連接。

對(duì)連接的管理也使用了池化技術(shù):每當(dāng)有一個(gè)客戶端進(jìn)程連接到服務(wù)器進(jìn)程時(shí),服務(wù)器進(jìn)程都會(huì)創(chuàng)建一個(gè)線程來專門處理與這個(gè)客戶端的交互,當(dāng)該客戶端退出時(shí)會(huì)與服務(wù)器斷開連接,服務(wù)器并不會(huì)立即把與該客戶端交互的線程銷毀掉,而是把它緩存起來,在另一個(gè)新的客戶端再進(jìn)行連接時(shí),把這個(gè)緩存的線程分配給該新客戶端。這樣就起到了不頻繁創(chuàng)建和銷毀線程的效果,從而節(jié)省開銷。

查詢緩存

由于表經(jīng)常更新,查詢緩存的失效頻繁,查詢緩存往往利大于弊。,MySQL 8.0 版本開始直接將查詢緩存的整塊功能刪掉了。

語法解析

如果查詢緩存沒有命中,接下來就需要進(jìn)入正式的查詢階段了。因?yàn)榭蛻舳顺绦虬l(fā)送過來的請(qǐng)求只是一段文本而已,所以MySQL服務(wù)器程序首先要對(duì)這段文本做分析,判斷請(qǐng)求的語法是否正確,然后從文本中將要查詢的表、各種查詢條件都提取出來放到MySQL服務(wù)器內(nèi)部使用的一些數(shù)據(jù)結(jié)構(gòu)上來。

查詢優(yōu)化

經(jīng)過了語法解析,MySQL 就知道你要做什么了。在開始執(zhí)行之前,還要先經(jīng)過查詢優(yōu)化的處理。優(yōu)化處理是指在表里面有多個(gè)索引的時(shí)候,決定使用哪個(gè)索引;或者在一個(gè)語句有多表關(guān)聯(lián)(join)的時(shí)候,決定各個(gè)表的連接順序。我們可以使用EXPLAIN語句來查看某個(gè)語句的執(zhí)行計(jì)劃 。

大部分優(yōu)化的邏輯是基于成本的優(yōu)化。在MySQL中一條查詢語句的執(zhí)行成本是由兩個(gè)方面組成的 :

  • I/O成本 :從磁盤到內(nèi)存這個(gè)加載的過程損耗的時(shí)間稱之為I/O成本。
  • CPU成本 :讀取以及檢測(cè)記錄是否滿足對(duì)應(yīng)的搜索條件、對(duì)結(jié)果集進(jìn)行排序等這些操作損耗的時(shí)間稱之為CPU成本。

對(duì)于InnoDB存儲(chǔ)引擎來說 ,mysql規(guī)定讀取一個(gè)頁(yè)面花費(fèi)的成本默認(rèn)是1.0,讀取以及檢測(cè)一條記錄是否符合搜索條件的成本默認(rèn)是0.2 。

拿單表查詢來舉例,成本計(jì)算步驟如下:

  • 根據(jù)搜索條件,找出所有可能使用的索引
  • 計(jì)算全表掃描的代價(jià)
  • 計(jì)算使用不同索引執(zhí)行查詢的代價(jià)
  • 對(duì)比各種執(zhí)行方案的代價(jià),找出成本最低的那一個(gè)。

存儲(chǔ)引擎

  • 截止到服務(wù)器程序完成了查詢優(yōu)化為止,還沒有真正的去訪問真實(shí)的數(shù)據(jù)表,MySQL服務(wù)器把數(shù)據(jù)的存儲(chǔ)和提取操作都封裝到了一個(gè)叫存儲(chǔ)引擎的模塊里。我們知道表是由一行一行的記錄組成的,但這只是一個(gè)邏輯上的概念,物理上如何表示記錄,怎么從表中讀取數(shù)據(jù),怎么把數(shù)據(jù)寫入具體的物理存儲(chǔ)器上,這都是存儲(chǔ)引擎負(fù)責(zé)的事情。為了實(shí)現(xiàn)不同的功能,MySQL提供了各式各樣的存儲(chǔ)引擎,不同存儲(chǔ)引擎管理的表具體的存儲(chǔ)結(jié)構(gòu)可能不同,采用的存取算法也可能不同。
  • 為了管理方便,所以大部分人把連接管理、查詢緩存、語法解析、查詢優(yōu)化這些并不涉及真實(shí)數(shù)據(jù)存儲(chǔ)的功能劃分為MySQL server的功能,
  • 把真實(shí)存取數(shù)據(jù)的功能劃分為存儲(chǔ)引擎的功能。

執(zhí)行器

執(zhí)行器就是各種不同的存儲(chǔ)引擎向上邊的MySQL server層提供統(tǒng)一的調(diào)用接口(也就是存儲(chǔ)引擎API),包含了幾十個(gè)底層函數(shù),像"讀取索引第一條內(nèi)容"、"讀取索引下一條內(nèi)容"、"插入記錄"等等。

比如執(zhí)行一條查詢sql 時(shí),開始執(zhí)行的時(shí)候,要先判斷一下你對(duì)這個(gè)表 有沒有執(zhí)行查詢的權(quán)限,如果沒有,就會(huì)返回沒有權(quán)限的錯(cuò)誤;

拿我們開頭的例子中,id字段沒有索引,那么執(zhí)行器的執(zhí)行流程是這樣的:

  • 調(diào)用 InnoDB 引擎接口取這個(gè)表的第一行,判斷 ID 值是不是 10,如果不是則跳過,如果是則將這行存在結(jié)果集中;
  • 調(diào)用引擎接口取“下一行”,重復(fù)相同的判斷邏輯,直到取到這個(gè)表的最后一行。
  • 執(zhí)行器將上述遍歷過程中所有滿足條件的行組成的記錄集作為結(jié)果集返回給客戶端。

對(duì)于有索引的表,執(zhí)行的邏輯也差不多。第一次調(diào)用的是“取滿足條件的第一行”這個(gè)接口,之后循環(huán)取“滿足條件的下一行”這個(gè)接口,這些接口都是引擎中已經(jīng)定義好的。但是對(duì)于 插入、刪除和修改的sql語句,還要涉及到redolog、undolog 和binlog 的操作。這個(gè)我們有空再聊。

所以只需按照生成的執(zhí)行計(jì)劃調(diào)用底層存儲(chǔ)引擎提供的API(執(zhí)行器),獲取到數(shù)據(jù)后返回給客戶端就好了。一條sql 語句就執(zhí)行完成了。

 

責(zé)任編輯:姜華 來源: 今日頭條
相關(guān)推薦

2022-05-31 13:58:09

MySQL查詢語句

2019-11-12 14:41:41

Redis程序員Linux

2021-01-18 08:23:23

內(nèi)存時(shí)底層CPU

2021-11-23 23:31:43

C語言數(shù)據(jù)類型系統(tǒng)

2020-08-20 11:50:31

語言類型轉(zhuǎn)換代碼

2023-03-31 08:12:30

操作系統(tǒng)nanosleep信號(hào)

2022-05-26 23:36:36

SQLMySQL數(shù)據(jù)

2025-07-28 06:32:12

Gogo func()

2020-08-17 12:47:07

Mozilla裁員瀏覽器

2019-08-26 09:35:25

命令ping抓包

2010-02-07 09:00:29

AndroidLinux Kerne

2021-04-11 10:40:16

Git軟件開發(fā)

2023-08-29 16:26:20

Linux命令行

2021-12-16 15:58:48

Linux內(nèi)存微軟

2020-09-01 11:40:01

HTTPJavaTCP

2015-07-03 09:27:43

網(wǎng)絡(luò)閏秒

2022-06-03 08:12:52

InnoDB插入MySQL

2019-09-16 17:16:29

Hadoop數(shù)據(jù)湖數(shù)據(jù)結(jié)構(gòu)

2018-11-05 14:54:18

MySQLSQL語句數(shù)據(jù)庫(kù)

2017-09-06 16:20:51

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)