欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MySql執(zhí)行流程與生命周期詳解

 更新時(shí)間:2022年09月13日 16:38:18   作者:π大星的日常  
當(dāng)你執(zhí)行一次MySQL查詢時(shí),有沒(méi)有仔細(xì)想過(guò),在查詢結(jié)果返回之前,經(jīng)過(guò)了哪些步驟呢?這些步驟有可能消耗了超出想象的時(shí)間和資源。因此,在對(duì)MySQL的查詢進(jìn)行優(yōu)化之前,應(yīng)該了解一下MySQL查詢的生命周期

我們經(jīng)常會(huì)在一起討論怎樣優(yōu)化 SQL、怎樣優(yōu)化數(shù)據(jù)庫(kù),那么請(qǐng)問(wèn)你知道執(zhí)行一條 SQL 的過(guò)程中都經(jīng)過(guò)了哪些動(dòng)作嗎?如果不知道的話,又怎么去優(yōu)化 SQL、優(yōu)化數(shù)據(jù)庫(kù)呢?為了更好地優(yōu)化 MySQL 數(shù)據(jù)庫(kù),接下來(lái)我們就來(lái)討論一下執(zhí)行一條 SQL 都經(jīng)過(guò)哪些步驟。

為了方便理解,在介紹 SQL 執(zhí)行流程之前,我們先通過(guò)一張圖,來(lái)詳細(xì)闡述一下 SQL 執(zhí)行流程。

由上圖,可以得出:在 MySQL 中,我們大致可以分為三個(gè)部分,分別是MySQL 客戶端、MySQL 服務(wù)端和存儲(chǔ)層。其中,存儲(chǔ)層主要是硬件層面,不在今天討論的范圍內(nèi),所以這里我們主要討論前兩者。

一、MySQL 客戶端

我們應(yīng)該都聽(tīng)說(shuō)過(guò) MySQL 數(shù)據(jù)庫(kù)支持很多編程語(yǔ)言的 API 接口,其實(shí)這句話底層的含義是很多編程語(yǔ)言是內(nèi)置 MySQL 客戶端。除此之外,MySQL 還有一個(gè)常用的客戶端就是 MySQL 數(shù)據(jù)庫(kù)自帶的一個(gè) mysql 命令,這個(gè)命令使用如下:

$ mysql -u$username -p$password -h$host -P$port
備注:
    - username 是用戶名
    - password 是密碼
    - host 是 MySQL 服務(wù)端地址
    - port 是 MySQL 服務(wù)端端口
復(fù)制代碼

一條 SQL 執(zhí)行的第一步是由 MySQL 客戶端發(fā)送到 MySQL 服務(wù)端。在這個(gè)步驟中直接影響數(shù)據(jù)速度的是網(wǎng)絡(luò),所以,數(shù)據(jù)庫(kù)服務(wù)端和客戶端之間最好要有良好的網(wǎng)絡(luò)環(huán)境。不過(guò),網(wǎng)絡(luò)不屬于本次討論的重點(diǎn),這里不做過(guò)多的討論。我們重點(diǎn)討論一下 MySQL 中的各個(gè)模塊對(duì)于數(shù)據(jù)庫(kù)速度的影響。

嚴(yán)格來(lái)說(shuō),MySQL 連接池屬于 MySQL 服務(wù)端的模塊,因其跟 MySQL 客戶端關(guān)系密切,我將其拿到 MySQL 客戶端中來(lái)介紹。

MySQL 客戶端成功連接 MySQL 服務(wù)端之后,MySQL 服務(wù)端的連接池會(huì)對(duì)客戶端的連接進(jìn)行權(quán)限驗(yàn)證,當(dāng)權(quán)限驗(yàn)證通過(guò)之后,MySQL 服務(wù)端會(huì)將客戶端的鏈接記錄在服務(wù)端的連接池中,之后的各種操作將不再進(jìn)行權(quán)限認(rèn)證。

這里你肯定會(huì)有疑問(wèn):為什么 MySQL 要增加一個(gè)連接池模塊呢?直接連接 MySQL 服務(wù)端不是更簡(jiǎn)單且高效嗎?下面我們就來(lái)分析一下。

每一次操作數(shù)據(jù)庫(kù),都需要有一個(gè) MySQL 客戶端和服務(wù)端之間的鏈接,創(chuàng)建一個(gè)鏈接就會(huì)有一定的時(shí)間消耗;當(dāng)在高并發(fā)的情況下,每一次訪問(wèn)數(shù)據(jù)都會(huì)創(chuàng)建一個(gè)鏈接,這樣就會(huì)持續(xù)創(chuàng)建很多重復(fù)的數(shù)據(jù)庫(kù)鏈接,很沒(méi)有必要而且大量的創(chuàng)建鏈接可能會(huì)導(dǎo)致數(shù)據(jù)庫(kù)內(nèi)存溢出等問(wèn)題。

為了解決這個(gè)問(wèn)題,MySQL 數(shù)據(jù)庫(kù)就提供了一個(gè)鏈接池模塊,主要用來(lái)保存和安全校驗(yàn)連接過(guò)來(lái)的客戶端,當(dāng)一個(gè)客戶端連接成功之后,并不會(huì)立即釋放該連接,而是會(huì)將該鏈接保存在連接池中,這樣下一次同一個(gè)客戶端連接過(guò)來(lái)就不需要再重復(fù)創(chuàng)建連接和安全驗(yàn)證了,可以在很大程度上降低數(shù)據(jù)庫(kù)的資源消耗并且減少連接數(shù)據(jù)的延時(shí)。

二、MySQL 服務(wù)端

在 MySQL 服務(wù)端中,SQL 執(zhí)行過(guò)程中是需要經(jīng)過(guò)很多模塊的,其中比較重要的模塊是緩存、SQL 解析器、查詢優(yōu)化器以及 SQL 執(zhí)行器等模塊。下面我來(lái)詳細(xì)介紹一下。

1. 查詢緩存

在 MySQL 數(shù)據(jù)庫(kù)中,如果開(kāi)啟了緩存查詢,每一次的查詢都會(huì)在緩存器中以 KV 形式緩存一份。一條 SQL 在執(zhí)行過(guò)程中,如果命中了緩存,就會(huì)跳過(guò) SQL 解析器、查詢優(yōu)化器以及 SQL 執(zhí)行器,并且立即返回?cái)?shù)據(jù),這樣做的目的主要是提高數(shù)據(jù)庫(kù)的性能。

其實(shí) MySQL 數(shù)據(jù)庫(kù)是將緩存以哈希的形式保存在內(nèi)存中的一個(gè)引用表中,并且把本次查詢的 SQL、數(shù)據(jù)庫(kù)名稱以及協(xié)議的 hash 值作為 key,這樣做的主要目的是下一次同一個(gè)查詢過(guò)來(lái)之后可以直接命中查詢。

不過(guò)緩存并不是永恒不變的,也會(huì)失效,我總結(jié)了以下幾個(gè)緩存失效的情況:

  • 該條緩存對(duì)應(yīng)的數(shù)據(jù)、數(shù)據(jù)表發(fā)生變化時(shí),緩存就會(huì)自動(dòng)失效;
  • 查詢過(guò)程中有變化的數(shù)據(jù)時(shí),是不會(huì)創(chuàng)建緩存的,例如 now()。

所以,在使用 MySQL 數(shù)據(jù)庫(kù)查詢的時(shí)候,要盡量避免更改數(shù)據(jù)和使用有變化的數(shù)據(jù)。

那么,既然緩存能夠提高 MySQL 數(shù)據(jù)的性能,應(yīng)該怎么設(shè)置開(kāi)啟緩存呢?首先,我們可以使用SHOW VARIABLES LIKE '%query_cache%';來(lái)查詢緩存的配置項(xiàng):

-- 查詢緩存配置項(xiàng)
mysql> SHOW VARIABLES LIKE '%query_cache%';
+------------------------------+---------+
| Variable_name                | Value   |
+------------------------------+---------+
| have_query_cache             | YES     |
| query_cache_limit            | 1048576 |
| query_cache_min_res_unit     | 4096    |
| query_cache_size             | 1048576 |
| query_cache_type             | OFF     |
| query_cache_wlock_invalidate | OFF     |
+------------------------------+---------+
6 rows in set (0.01 sec)

其中,query_cache_type有三個(gè)選項(xiàng),分別是:

  • OFF(0):關(guān)閉緩存。
  • ON(1):開(kāi)啟緩存。
  • DEMAND(2):按需開(kāi)啟緩存,加上 SQL_CACHE 關(guān)鍵字才會(huì)緩存。

所以,要開(kāi)啟查詢緩存可以在 MySQL 數(shù)據(jù)庫(kù)的配置文件 my.cnf 中添加query_cache_type = 1即可。如果需要使用 DEMAND 的話,就需要配置成query_cache_type = 2。如果需要緩存的話,就需要增加SQL_CACHE關(guān)鍵字,具體操作如下:

mysql> select SQL_CACHE * from info;
+----+--------------+
| id | name         |
+----+--------------+
|  1 | 小仙女       |
|  2 | 小帥哥       |
|  3 | 鐵錘妹妹     |
+----+--------------+
3 rows in set, 1 warning (0.00 sec)

2. SQL 解析器

當(dāng)沒(méi)有命中緩存時(shí),這個(gè)時(shí)候 MySQL 數(shù)據(jù)庫(kù)就得去查詢數(shù)據(jù)了。在查詢之前必須解析客戶端發(fā)送過(guò)來(lái)的以一系列字符串和空格組成的 SQL,此時(shí)就必須用到 MySQL 數(shù)據(jù)庫(kù)中的另一個(gè)模塊:SQL 解析器。

SQL 解析器的主要功能是解析客戶端發(fā)送過(guò)來(lái)的 SQL,就比如匹配到 SQL 中是以 select 開(kāi)頭的,那就可以認(rèn)定其為查詢語(yǔ)句;以 insert 開(kāi)頭的 SQL,就可以認(rèn)定其為插入語(yǔ)句。但如果在判斷的過(guò)程中,出現(xiàn)了匹配不到的這種情況,就會(huì)報(bào)出ERROR 1064 (42000): You have an error in your SQL syntax;的錯(cuò)誤。具體如下:

mysql> elect * from info;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'elect * from info' at line 1

一般情況下,具體的錯(cuò)誤信息都是在最后邊的單引號(hào)內(nèi),具體問(wèn)題具體對(duì)待。

3. 查詢優(yōu)化器

查詢優(yōu)化器,顧名思義就是優(yōu)化 SQL 的執(zhí)行效率,也就是說(shuō)查詢優(yōu)化器的具體功能是為了找到 SQL 的最佳執(zhí)行方案。

在 MySQL 數(shù)據(jù)庫(kù)中的查詢優(yōu)化器優(yōu)化 SQL 具體有兩個(gè)方面,分別是邏輯層面和物理層面。

物理層面主要是跟硬件有關(guān),很難通過(guò)邏輯去優(yōu)化,所以這里我們從邏輯層面說(shuō)明一下。

邏輯層面的優(yōu)化主要有命中索引優(yōu)化、順序優(yōu)化、排序優(yōu)化等。例如連表查詢,具體如下:

mysql> select * from province inner join city on city.fid = province.id where province.id = 1;
+----+-----------+----+--------------+------+
| id | name      | id | name         | fid  |
+----+-----------+----+--------------+------+
|  1 | 上海市    |  1 | 徐匯區(qū)         |    1 |
|  1 | 上海市    |  2 | 浦東新區(qū)       |    1 |
+----+-----------+----+--------------+------+
2 rows in set (0.00 sec)

上面的 SQL 連接 province 和 city 兩個(gè)數(shù)據(jù)表,在內(nèi)存中,有如下兩種情況。

  • 第一種情況:首先查詢 province 表中 id 為 1 的數(shù)據(jù),然后再查詢 city 表中 fid 為 1 的數(shù)據(jù)。
  • 第二種情況:首先查詢 city 表中的所有數(shù)據(jù),然后再判斷 city 表中的 fid 是否等于 1。

這兩種情況的結(jié)果是一樣的,這個(gè)時(shí)候查詢優(yōu)化器內(nèi)部通過(guò)算法的方式判斷哪個(gè)方案的效率更高,進(jìn)而選擇哪個(gè)方案。

4. SQL 執(zhí)行器

當(dāng)分析完 SQL 并且選擇合適的方案之后,就開(kāi)始執(zhí)行 SQL 了,執(zhí)行 SQL 就需要使用 MySQL 數(shù)據(jù)庫(kù)提供的 SQL 執(zhí)行器模塊。

SQL 執(zhí)行模塊首先會(huì)判斷當(dāng)前用戶是否對(duì)該表有相關(guān)的操作權(quán)限(如果命中了緩存,將會(huì)在返回緩存數(shù)據(jù)之前進(jìn)行權(quán)限認(rèn)證)。權(quán)限判斷通過(guò)之后才會(huì)調(diào)用存儲(chǔ)引擎去操作對(duì)應(yīng)的數(shù)據(jù)表,然后將操作的結(jié)果返回。

總結(jié)

在這篇文章中,我們按照 SQL 的執(zhí)行順序介紹了一條 SQL 從客戶端到返回?cái)?shù)據(jù)期間經(jīng)過(guò)的各個(gè)模塊。這里我簡(jiǎn)單將各個(gè)要點(diǎn)匯總一下。

  • MySQL 客戶端主要是用來(lái)將 SQL 發(fā)送至服務(wù)端的一個(gè)模塊。
  • 連接池主要是用來(lái)保存成功連接 MySQL 服務(wù)端的鏈接的,這樣做的好處是可以防止數(shù)據(jù)庫(kù)連接短時(shí)間內(nèi)不斷重復(fù)創(chuàng)建,減少了資源浪費(fèi),提高了數(shù)據(jù)庫(kù)的訪問(wèn)速度。
  • 數(shù)據(jù)庫(kù)緩存模塊是將之前訪問(wèn)過(guò)的數(shù)據(jù)保存在內(nèi)存中,這樣做的好處是避免相同的一個(gè)任務(wù)重復(fù)執(zhí)行的問(wèn)題,可以提高數(shù)據(jù)庫(kù)速度,并且也可以降低數(shù)據(jù)庫(kù)資源消耗。
  • SQL 解析器主要是用于解析 SQL 的,搞清楚這條 SQL 的具體目的——查詢還是更新數(shù)據(jù)。
  • SQL 優(yōu)化器是通過(guò)內(nèi)部的算法選擇執(zhí)行這條 SQL 效率最高的方案。
  • 搞清了 SQL 的具體操作,也選擇了最優(yōu)的執(zhí)行方案,最后就開(kāi)始執(zhí)行 SQL,SQL 執(zhí)行器的主要作用除了調(diào)用存儲(chǔ)引擎接口獲取數(shù)據(jù)之外,還有權(quán)限認(rèn)證的作用。

至此,一條 SQL 的生命周期就結(jié)束了。

在實(shí)際應(yīng)用中,我建議 SQL 緩存最好設(shè)置成按需開(kāi)啟(默認(rèn)是關(guān)閉狀態(tài)) ,原因是 MySQL 中的某一個(gè)表更新會(huì)導(dǎo)致與這個(gè)表相關(guān)的所有緩存全部失效,這樣更新數(shù)據(jù)庫(kù)時(shí)的開(kāi)銷就會(huì)額外增加很多。

到此這篇關(guān)于MySql執(zhí)行流程與生命周期詳解的文章就介紹到這了,更多相關(guān)MySql生命周期內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • mysql 搜尋附近N公里內(nèi)數(shù)據(jù)的簡(jiǎn)單實(shí)例

    mysql 搜尋附近N公里內(nèi)數(shù)據(jù)的簡(jiǎn)單實(shí)例

    下面小編就為大家?guī)?lái)一篇mysql 搜尋附近N公里內(nèi)數(shù)據(jù)的簡(jiǎn)單實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-04-04
  • MySQL實(shí)戰(zhàn)教程之Join語(yǔ)句執(zhí)行流程

    MySQL實(shí)戰(zhàn)教程之Join語(yǔ)句執(zhí)行流程

    這篇文章主要介紹了MySQL Join語(yǔ)句執(zhí)行流程,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-03-03
  • MySQL中基本的多表連接查詢教程

    MySQL中基本的多表連接查詢教程

    這篇文章主要介紹了MySQL中基本的多表連接查詢教程,附帶了JOIN的基本連接用法講解,需要的朋友可以參考下
    2015-11-11
  • MySQL 索引的優(yōu)缺點(diǎn)以及創(chuàng)建索引的準(zhǔn)則

    MySQL 索引的優(yōu)缺點(diǎn)以及創(chuàng)建索引的準(zhǔn)則

    這篇文章主要介紹了MySQL 索引的優(yōu)劣以及創(chuàng)建索引的準(zhǔn)則,幫助大家更好的理解和使用MySQL 索引,感興趣的朋友可以了解下
    2020-09-09
  • mysql5.7.20 安裝配置方法圖文教程(win10)

    mysql5.7.20 安裝配置方法圖文教程(win10)

    這篇文章主要為大家詳細(xì)介紹了win10下mysql5.7.20 安裝配置方法圖文教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-09-09
  • MySQL 配置免密碼登錄的問(wèn)題記錄(mysql_config_editor Configuration)

    MySQL 配置免密碼登錄的問(wèn)題記錄(mysql_config_editor Configurati

    這篇文章主要介紹了MySQL 配置免密碼登錄的問(wèn)題記錄(mysql_config_editor Configuration),本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-08-08
  • 一文詳解MYSQL最樸素的監(jiān)控方式

    一文詳解MYSQL最樸素的監(jiān)控方式

    對(duì)于當(dāng)前數(shù)據(jù)庫(kù)的監(jiān)控方式有很多,分為數(shù)據(jù)庫(kù)自帶、商用、開(kāi)源三大類,每一種都有各自的特色,那我們今天就介紹一下完全采用mysql自有方式采集獲取監(jiān)控?cái)?shù)據(jù),在單體下達(dá)到最快速、方便、損耗最小,感興趣的同學(xué)可以借鑒閱讀
    2023-05-05
  • mysql本地登錄無(wú)法使用端口號(hào)登錄的解決方法

    mysql本地登錄無(wú)法使用端口號(hào)登錄的解決方法

    這篇文章主要介紹了mysql本地登錄無(wú)法使用端口號(hào)登錄的解決方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2018-06-06
  • MySQL中的ibdata1用法解讀

    MySQL中的ibdata1用法解讀

    這篇文章主要介紹了MySQL中的ibdata1用法解讀,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • MySQL Limit執(zhí)行過(guò)程分析探索

    MySQL Limit執(zhí)行過(guò)程分析探索

    limit是MySql的內(nèi)置函數(shù),一般用于查詢表中記錄的條數(shù),作用是用于限制查詢條數(shù),下面這篇文章主要給大家介紹了關(guān)于SQL中l(wèi)imit函數(shù)語(yǔ)法與用法的相關(guān)資料,詳細(xì)講了MySQL Limit執(zhí)行過(guò)程
    2022-12-12

最新評(píng)論