0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

一條SQL查詢語句是怎么去執(zhí)行的?(上)

jf_78858299 ? 來源:蟬沐風(fēng)的碼場 ? 作者:蟬沐風(fēng) ? 2023-03-03 09:58 ? 次閱讀

MySQL是典型的C/S架構(gòu)(客戶端/服務(wù)器架構(gòu)),客戶端進(jìn)程向服務(wù)端進(jìn)程發(fā)送一段文本(MySQL指令),服務(wù)器進(jìn)程進(jìn)行語句處理然后返回執(zhí)行結(jié)果。

問題來了。服務(wù)器進(jìn)程對客戶端發(fā)送的請求究竟做了什么處理呢?本文以查詢請求為例,講解MySQL服務(wù)器進(jìn)程的處理流程。

如下圖所示,服務(wù)器進(jìn)程在處理客戶端請求的時候,大致需要進(jìn)行3個步驟:

  • 處理連接
  • 解析與優(yōu)化
  • 存儲引擎

接下來我們來詳細(xì)了解一下這3步具體都做了什么。圖片

1. 處理連接

客戶端向服務(wù)器發(fā)送請求并最終收到響應(yīng),本質(zhì)上是一個進(jìn)程間通信的過程。

MySQL有專門用于處理連接的模塊——連接器。

1.1 客戶端和服務(wù)端的通信方式

1.1.1 TCP/IP協(xié)議

TCP/IP協(xié)議是MySQL客戶端和服務(wù)器最常用的通信方式。

我們平時所說的MySQL服務(wù)器默認(rèn)監(jiān)聽的端口3306,這句話的前提是客戶端進(jìn)程和服務(wù)器進(jìn)程使用的是TCP/IP協(xié)議進(jìn)行通信。

我們在使用mysql命令啟動客戶端程序時,只要在-h參數(shù)后跟隨IP地址作為服務(wù)器進(jìn)程所在的主機(jī)地址,那么通訊方式便是TCP/IP協(xié)議。

如果客戶端進(jìn)程和服務(wù)器進(jìn)程位于同一臺主機(jī),且要使用TCP/IP協(xié)議進(jìn)行通信,則IP地址需要指定為127.0.0.1,而不能使用localhost

1.1.2 UNIX域套接字

如果客戶端進(jìn)程和服務(wù)器進(jìn)程都位于類UNIX操作系統(tǒng)(MacOS、Centos、Ubuntu等)的主機(jī)之上,并且在啟動客戶端程序時沒有指定主機(jī)名,或者指定的主機(jī)名為localhost,又或者指定了--protocol=socket的啟動參數(shù),那么客戶端進(jìn)程和服務(wù)器進(jìn)程就會使用UNIX域套接字進(jìn)行進(jìn)程間通信。

MySQL服務(wù)器進(jìn)程默認(rèn)監(jiān)聽的UNIX域套接字文件為/temp/mysql.sock,客戶端進(jìn)程啟動時也默認(rèn)會連接到這個UNIX域套接字文件之上。

如果不明白UNIX域套接字到底是什么也沒關(guān)系,只要知道這是進(jìn)程之間的一種通訊方式就可以了,這里提及的主要目的是希望讀者知曉MySQL客戶端和進(jìn)程通訊方式不止于TCP/IP協(xié)議

1.1.3 命名管道和共享內(nèi)存

如果你的MySQL是安裝在Windows主機(jī)之上,客戶端和服務(wù)器進(jìn)程可以使用命名管道和共享內(nèi)存的方式進(jìn)行通信。

不過使用這些通信方式需要在服務(wù)端和客戶端啟動時添加一些啟動參數(shù)。

  • 使用命名管道進(jìn)行通信。需要在啟動服務(wù)器時添加--enable-named-pipe參數(shù),同時在啟動客戶端進(jìn)程時添加--pipe或者--protocol=pipe參數(shù)
  • 使用共享內(nèi)存進(jìn)行通信。需要在啟動服務(wù)器時添加--shared-memory參數(shù),啟動成功后,共享內(nèi)存便成為本地客戶端程序的默認(rèn)連接方式;也可以在啟動客戶端進(jìn)程的命令中加上--protocol=memory參數(shù)明確指定使用共享內(nèi)存進(jìn)行通信

如果不明白命名管道和共享內(nèi)存到底是什么沒關(guān)系,只要知道這是進(jìn)程之間的一種通訊方式就可以了,這里提及的主要目的是希望讀者知曉MySQL客戶端和進(jìn)程通訊方式不止于TCP/IP協(xié)議

1.2 權(quán)限驗證

確認(rèn)通信方式并且成功建立連接之后,連接器就要開始驗證你的身份了,使用的信息就是你的用戶名和密碼。

  • 如果用戶名或者密碼錯誤,客戶端連接會立即斷開
  • 如果用戶名密碼認(rèn)證通過,連接器會到權(quán)限表里面查出當(dāng)前登陸用戶擁有的權(quán)限。之后這個連接里面的權(quán)限判斷邏輯,都將依賴于此時讀到的權(quán)限。

1.3 查看MySQL連接

每當(dāng)一個客戶端連接到服務(wù)端時,服務(wù)端進(jìn)程都會創(chuàng)建一個單獨的線程來處理當(dāng)前客戶端的交互操作。

那么如何查看MySQL當(dāng)前所有的連接?

mysql> show global status like 'Thread%';

+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_cached    | 0     |
| Threads_connected | 1     |
| Threads_created   | 1     |
| Threads_running   | 1     |
+-------------------+-------+

各字段含義如下表

字段 含義
Threads_cached 緩存中的線程連接數(shù)
Threads_connected 當(dāng)前打開的連接數(shù)
Threads_created 為處理連接創(chuàng)建的線程數(shù)
Threads_running 非睡眠狀態(tài)的連接數(shù),通常指并發(fā)連接數(shù)

建立連接之后,除非客戶端主動斷開連接,否則服務(wù)器會等待客戶端發(fā)送請求。但是線程的創(chuàng)建和保持是需要消耗服務(wù)器資源的,因此服務(wù)器會把長時間不活動的客戶端連接斷開。

有2個參數(shù)控制這個自動斷開連接的行為,每個參數(shù)都默認(rèn)為28800秒,8小時。

-- 非交互式超時時間,如JDBC連接
mysql> show global variables like 'wait_timeout';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout  | 28800 |
+---------------+-------+

-- 交互式超時時間,如數(shù)據(jù)庫查看工具Navicat等
mysql> show global variables like 'interactive_timeout';
+---------------------+-------+
| Variable_name       | Value |
+---------------------+-------+
| interactive_timeout | 28800 |
+---------------------+-------+

既然連接消耗資源,那是不是MySQL的最大連接數(shù)也有默認(rèn)限制呢?沒錯!默認(rèn)最大連接數(shù)為151。

mysql> show variables like 'max_connections';
+-----------------+-------+
| Variable_name   | Value |
+-----------------+-------+
| max_connections | 151   |
+-----------------+-------+

題外話:細(xì)心的讀者可能會發(fā)現(xiàn)MySQL某些查詢語句帶有global關(guān)鍵字,這個關(guān)鍵字有什么含義呢?

MySQL的系統(tǒng)變量有兩個作用范圍(不區(qū)分大小寫),分別是

  • GLOBAL(全局范圍):變量的設(shè)置影響服務(wù)器和所有客戶端
  • SESSION(會話范圍):變量的設(shè)置僅影響當(dāng)前連接(會話)

但是并非每個參數(shù)都具有兩個作用范圍,比如允許同時連接到服務(wù)器的客戶端的數(shù)量max_connections就只有全局級別。

當(dāng)沒有帶作用范圍關(guān)鍵字時,默認(rèn)是SESSION級別,包括查詢和修改操作。

比如修改一個參數(shù)之后,在當(dāng)前窗口生效了,但是在其他窗口卻沒有生效

show VARIABLES like 'autocommit';
set autocommit = on;

因此,如果只是臨時修改,請使用SESSION級別,如果需要當(dāng)前設(shè)置在其他會話中生效,需要使用GLOBAL關(guān)鍵字。

到此為止,服務(wù)器進(jìn)程已經(jīng)和客戶端進(jìn)程建立了連接,下一步將處理客戶端傳來的請求了。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 服務(wù)器
    +關(guān)注

    關(guān)注

    12

    文章

    8701

    瀏覽量

    84554
  • TCP
    TCP
    +關(guān)注

    關(guān)注

    8

    文章

    1324

    瀏覽量

    78757
  • MySQL
    +關(guān)注

    關(guān)注

    1

    文章

    789

    瀏覽量

    26285
  • 服務(wù)端
    +關(guān)注

    關(guān)注

    0

    文章

    66

    瀏覽量

    6947
收藏 人收藏

    評論

    相關(guān)推薦

    STM8L執(zhí)行一條語句大概需要幾個時鐘周期?

    STM8L執(zhí)行一條語句大概需要幾個時鐘周期
    發(fā)表于 05-06 06:16

    在Delphi中動態(tài)地使用SQL查詢語句

    在Delphi中動態(tài)地使用SQL查詢語句般的數(shù)據(jù)庫管理系統(tǒng)中,通常都需要應(yīng)用SQL查詢
    發(fā)表于 05-10 11:10

    DSP執(zhí)行一條語句的時間

    CPU配置成150M。高頻時鐘75M。 那么執(zhí)行一條語句的時間是多少呢
    發(fā)表于 10-15 11:28

    select語句和update語句分別是怎么執(zhí)行

    樣,但是具體的實現(xiàn)還是有區(qū)別的。 當(dāng)然深入了解select和update的具體區(qū)別并不是只為了面試,當(dāng)希望Mysql能夠高效的執(zhí)行的時候,最好的辦法就是清楚的了解Mysql是如何執(zhí)行查詢
    的頭像 發(fā)表于 11-03 09:41 ?3411次閱讀
    select<b class='flag-5'>語句</b>和update<b class='flag-5'>語句</b>分別是怎么<b class='flag-5'>執(zhí)行</b>的

    一條SQL語句是怎么被執(zhí)行

    直是想知道一條SQL語句是怎么被執(zhí)行的,它執(zhí)行的順序是怎樣的,然后查看總結(jié)各方資料,就有了下面
    的頭像 發(fā)表于 09-12 09:44 ?1442次閱讀
    <b class='flag-5'>一條</b><b class='flag-5'>SQL</b><b class='flag-5'>語句</b>是怎么被<b class='flag-5'>執(zhí)行</b>的

    簡述SQL更新語句執(zhí)行流程1

    之前我們講過了一條SQL查詢語句是如何執(zhí)行的,那么插入(INSERT)、更新(UPDATE)和刪除(DELETE)操作的流程又是什么樣子呢?
    的頭像 發(fā)表于 02-14 15:40 ?536次閱讀
    簡述<b class='flag-5'>SQL</b>更新<b class='flag-5'>語句</b>的<b class='flag-5'>執(zhí)行</b>流程1

    簡述SQL更新語句執(zhí)行流程2

    之前我們講過了一條SQL查詢語句是如何執(zhí)行的,那么插入(INSERT)、更新(UPDATE)和刪除(DELETE)操作的流程又是什么樣子呢?
    的頭像 發(fā)表于 02-14 15:40 ?458次閱讀
    簡述<b class='flag-5'>SQL</b>更新<b class='flag-5'>語句</b>的<b class='flag-5'>執(zhí)行</b>流程2

    一條SQL查詢語句是怎么執(zhí)行的?(中)

    MySQL是典型的`C/S架構(gòu)`(客戶端/服務(wù)器架構(gòu)),客戶端進(jìn)程向服務(wù)端進(jìn)程發(fā)送段文本(MySQL指令),服務(wù)器進(jìn)程進(jìn)行語句處理然后返回執(zhí)行結(jié)果。
    的頭像 發(fā)表于 03-03 09:58 ?384次閱讀
    <b class='flag-5'>一條</b><b class='flag-5'>SQL</b><b class='flag-5'>查詢</b><b class='flag-5'>語句</b>是怎么<b class='flag-5'>去</b><b class='flag-5'>執(zhí)行</b>的?(中)

    一條SQL查詢語句是怎么執(zhí)行的?(下)

    MySQL是典型的`C/S架構(gòu)`(客戶端/服務(wù)器架構(gòu)),客戶端進(jìn)程向服務(wù)端進(jìn)程發(fā)送段文本(MySQL指令),服務(wù)器進(jìn)程進(jìn)行語句處理然后返回執(zhí)行結(jié)果。
    的頭像 發(fā)表于 03-03 09:58 ?336次閱讀
    <b class='flag-5'>一條</b><b class='flag-5'>SQL</b><b class='flag-5'>查詢</b><b class='flag-5'>語句</b>是怎么<b class='flag-5'>去</b><b class='flag-5'>執(zhí)行</b>的?(下)

    SQL語句和自定義查詢在導(dǎo)入包中可用

    在高級任務(wù)編輯器模式下,您可以選擇要使用的操作-自己鍵入和編輯任何復(fù)雜性的SQL語句執(zhí)行命令)或通過我們的可視化查詢構(gòu)建器(執(zhí)行
    的頭像 發(fā)表于 04-16 09:13 ?1054次閱讀

    sql查詢語句大全及實例

    SQL(Structured Query Language)是種專門用于數(shù)據(jù)庫管理系統(tǒng)的標(biāo)準(zhǔn)交互式數(shù)據(jù)庫查詢語言。它被廣泛應(yīng)用于數(shù)據(jù)庫管理和數(shù)據(jù)操作領(lǐng)域。在本文中,我們將為您詳細(xì)介紹SQL
    的頭像 發(fā)表于 11-17 15:06 ?1160次閱讀

    sql where條件的執(zhí)行順序

    。 在深入討論WHERE條件的執(zhí)行順序之前,先回顧一下一SQL語句執(zhí)行順序。一條
    的頭像 發(fā)表于 11-23 11:31 ?1863次閱讀

    oracle執(zhí)行sql查詢語句的步驟是什么

    Oracle數(shù)據(jù)庫是種常用的關(guān)系型數(shù)據(jù)庫管理系統(tǒng),具有強大的SQL查詢功能。Oracle執(zhí)行SQL查詢
    的頭像 發(fā)表于 12-06 10:49 ?774次閱讀

    MySQL執(zhí)行過程:如何進(jìn)行sql 優(yōu)化

    (1)客戶端發(fā)送一條查詢語句到服務(wù)器; (2)服務(wù)器先查詢緩存,如果命中緩存,則立即返回存儲在緩存中的數(shù)據(jù); (3)未命中緩存后,MySQL 通過關(guān)鍵字將
    的頭像 發(fā)表于 12-12 10:19 ?333次閱讀
    MySQL<b class='flag-5'>執(zhí)行</b>過程:如何進(jìn)行<b class='flag-5'>sql</b> 優(yōu)化

    查詢SQL在mysql內(nèi)部是如何執(zhí)行?

    我們知道在mySQL客戶端,輸入一條查詢SQL,然后看到返回查詢的結(jié)果。這條查詢語句在 MySQ
    的頭像 發(fā)表于 01-22 14:53 ?407次閱讀
    <b class='flag-5'>查詢</b><b class='flag-5'>SQL</b>在mysql內(nèi)部是如何<b class='flag-5'>執(zhí)行</b>?