最近中文字幕高清中文字幕无,亚洲欧美高清一区二区三区,一本色道无码道dvd在线观看 ,一个人看的www免费高清中文字幕

MySQL 邏輯架構(gòu)

從整體架構(gòu)切入MySQL的學(xué)習(xí),可以對 MySQL 有一個整體的把握,鳥瞰全貌,不至于一下陷入細(xì)節(jié)里邊, 對于以后深入理解 MySQL 也是有很大幫助的。本文通過講解一條查詢語句在 MySQL 內(nèi)部的執(zhí)行過程,讓您對 MySQL 邏輯架構(gòu)有更深的了解。

1. 邏輯架構(gòu)組成

圖片描述上方是 MySQL 邏輯架構(gòu)的簡單示意圖,總的來說,MySQL 包含 Server 層和存儲引擎層兩大部分。

Server 層包括連接池、查詢緩存、解析器、優(yōu)化器、執(zhí)行器等,MySQL 的核心服務(wù)都在這一層。

存儲引擎層負(fù)責(zé)數(shù)據(jù)的存儲和提取,MySQL 采用插件式的存儲引擎,常見的存儲引擎有 InnoDB、MyISAM、 CSV 等。其中 InnoDB 是最常用的存儲引擎,也是 MySQL 的默認(rèn)存儲引擎(從5.5.5版本開始)。

2. 一條查詢語句是如何執(zhí)行的

上一小節(jié)介紹了 MySQL 的邏輯架構(gòu)組成,那么各模塊之間是如何協(xié)同工作的呢?這里以一條最簡單的查詢語句為例子,我們一起來看看這條語句在 MySQL 內(nèi)部是如何執(zhí)行的。

select id from a where id=1;

2.1 連接池

首先,我們通過 mysql 這個客戶端工具進(jìn)行數(shù)據(jù)庫的連接,這時遇到的是連接池。連接池負(fù)責(zé)客戶端的連接管理、授權(quán)認(rèn)證。

連接命令如下(輸入完連接命令后,需要輸入用戶密碼):

mysql -h localhost -u root -p
  • 如果用戶名和密碼認(rèn)證通過,連接池會通過權(quán)限表獲取這個用戶名所擁有的權(quán)限信息;

  • 如果用戶名或密碼認(rèn)證不通過,則會收到一個錯誤提示:“ERROR 1045 (28000): Access denied for user ‘root’@‘localhost’”;

建立連接后,會產(chǎn)生相應(yīng)的連接信息,可以通過 show processlist 命令查看。下方圖中 Id 為 5048 這一行,即為成功連接數(shù)據(jù)庫所建立的連接信息,請注意 Command 這一列,值為”Sleep“,表明這是一個空閑連接。成功連接數(shù)據(jù)庫后,如果沒有任何動作,這個連接就會變成空閑狀態(tài)。

root@localhost [(none)]>show processlist;
+------+------+-----------+------+---------+------+----------+------------------+
| Id   | User | Host      | db   | Command | Time | State    | Info             |
+------+------+-----------+------+---------+------+----------+------------------+
| 4771 | root | localhost | NULL | Query   |    0 | starting | show processlist |
| 5048 | root | localhost | NULL | Sleep   |    3 |          | NULL             |
+------+------+-----------+------+---------+------+----------+------------------+
2 rows in set (0.00 sec)

2.2 查詢緩存

連接成功建立后,來到第二步查詢緩存。查詢緩存負(fù)責(zé)將執(zhí)行過的語句和結(jié)果緩存在內(nèi)存中。

在獲取一個查詢請求后,MySQL會先到查詢緩存進(jìn)行查看

  • 如果select語句在查詢緩存中能夠找到,則直接返回結(jié)果給客戶端,跳過解析、優(yōu)化、執(zhí)行階段。
  • 如果select語句沒能在查詢緩存中找到,則繼續(xù)后面的解析、優(yōu)化、執(zhí)行階段。

從這里可以看到,如果命中查詢緩存,MySQL 會直接返回結(jié)果給客戶端,后面的一系列操作不需要再執(zhí)行,是非常高效的。但實(shí)際情況并非如此,查詢緩存非常容易失效

因?yàn)橹灰?strong>一個表有更新操作,那這個表所有的查詢緩存都會被清空。對一個承載正常業(yè)務(wù)的數(shù)據(jù)庫來說,更新操作是非常頻繁的,這就意味著查詢緩存經(jīng)常失效,從而導(dǎo)致查詢緩存的命中率非常低。所以,使用查詢緩存反而會給數(shù)據(jù)庫帶來額外的負(fù)擔(dān),在實(shí)際生產(chǎn)環(huán)境中,我們建議關(guān)閉查詢緩存

關(guān)閉查詢緩存的方法有兩種:

  • 臨時:在 MySQL 中直接用命令行執(zhí)行;

    set global query_cache_size=0
    set global query_cache_type=0
    
  • 永久:將以下兩個參數(shù)添加至配置文件 my.cnf,并重啟 MySQL;

    query_cache_type=0
    query_cache_size=0
    

2.3 解析器

如果沒有命中查詢緩存,接下來就要進(jìn)入解析器階段了。解析器負(fù)責(zé)詞法解析和語法解析。

首先是詞法解析,MySQL 需要識別所輸入的字符串分別代表什么,它會從左到右一個字符、一個字符地輸入,然后根據(jù)構(gòu)詞規(guī)則識別單詞。

select id from a where id=1;
關(guān)鍵字 非關(guān)鍵字 關(guān)鍵字 非關(guān)鍵字 關(guān)鍵字 非關(guān)鍵字
select 字段id from 表名a where 字段id等于1

接下來是語法解析,判斷輸入的這個SQL語句是否符合MySQL語法規(guī)則。如果語法不對,會收到錯誤信息提示:“ERROR 1064 (42000): You have an error in your SQL syntax;”。如下面這個SQL語句的where少了一個e。

root@localhost [tempdb]>select id from a wher id=1;
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 'id=1' at line 1

2.4 優(yōu)化器

從解析器出來,就到了優(yōu)化器階段。優(yōu)化器負(fù)責(zé)找到最優(yōu)的執(zhí)行計劃,也就是決定SQL語句的執(zhí)行方案。

一條查詢可以有很多種執(zhí)行方式,最后都返回相同的結(jié)果 。比如下面這個查詢SQL,查詢表a中字段id等于1的值

select id from a where id=1;
  • 可以遍歷表a所有行,找出所有id等于1的值
  • 也可以通過索引idx_id,找到id等于1的值。當(dāng)然,前提是字段id有創(chuàng)建索引idx_id。

兩種方案的結(jié)果是一樣的,但是執(zhí)行效率不一樣,優(yōu)化器的作用就是選擇最優(yōu)的執(zhí)行方案。

2.5 執(zhí)行器

現(xiàn)在到了執(zhí)行SQL語句的階段,也就是執(zhí)行器。執(zhí)行器負(fù)責(zé)調(diào)用存儲引擎,拿到查詢結(jié)果。

select id from a where id=1;

假設(shè)這個例子中的字段id沒有索引,執(zhí)行器的流程大致如下:

  1. 調(diào)用 InnoDB 引擎接口獲取表 a 的第一行,如果 id 值等于 1,則將 id 值存進(jìn)結(jié)果集,如果 id 值不等于 1,則跳過,取下一行;
  2. 調(diào)用 InnoDB 引擎接口獲取下一行,重復(fù)第一步的邏輯,一直到表 a 的最后一行;
  3. 將符合查詢條件的結(jié)果集返回給客戶端。

3. 小結(jié)

一條 SQL 查詢的過程,大致就是這樣的流程:連接池、查詢緩存、解析器、優(yōu)化器、執(zhí)行器。

連接池負(fù)責(zé)連接管理,查詢緩存建議關(guān)閉,解析器讓 MySQL 知道要做什么,優(yōu)化器讓 MySQL 知道怎么做,執(zhí)行器負(fù)責(zé)執(zhí)行取數(shù)。

通過本文的講解,對您認(rèn)識 MySQL 邏輯架構(gòu),有所幫助嗎?歡迎反饋寶貴意見,以便我們不斷改進(jìn)。