通過一條Sql語句俯瞰MySql基礎架構

1 前言

最近一直在學習MySql整理一下學習心得。要相信堅持不懈的抓着一塊東西學習,一定能學明白!

2 整體俯瞰MySql

爲了好理解,我們以一條簡單的Sql語句開始 ,假設T表中只有一個ID字段

	mysql>  select * from T where ID=10;

這條語句看似簡單,但是我們不能僅僅得到一個結果,而要通過這條語句來探究MySql內部的執行過程。接下來我們一起來拆解MySql.
當執行這條Sql語句的時候,MySql內部是這樣執行的:
在這裏插入圖片描述

3 Server層和存儲引擎層介紹

大體MySql可以分爲二層:Server層和存儲層二部分。

1.server層 :本層涵蓋了MySql的大部分核心服務功能,以及所有的內置函數,所有跨存儲引擎的功能都在這一層實現,比如存儲過程,觸發器,視圖等。主要包括:連接器,查詢緩存,分析器,優化器,執行器等。
2.存儲引擎層負責數據的讀取和存儲,MySql的存儲引擎主要有以下幾種:InnoDB、MyISAM、Memory等多個存儲引擎。5.5.5之後InnoDB成爲了默認存儲引擎。
也就是說,在執行 create table 時,如果不指定存儲引擎類型,默認的就是InnoDB.當然我們在建表的時候也可以指定存儲引擎。

3.1 server層內部介紹

1.連接器:當你使用數據庫時首先要和連接器打交道,連接器負責:與客戶端建立連接,獲取權限,維持和管理連接。

	mysqli_connect(host,username,password,dbname,port,socket);

這條命令就是在和連接器打交道,這條語句一旦執行成功表示一個用戶成功建立了連接。請注意,如果這時你用管理員賬號強制修改了當前用戶的權限也不會影響已經存在的連接權限。只有當這個用戶重新連接的時候纔會使用新的權限設置。

連接成功後如果沒有後續操作,這個連接就會處於空閒狀態,如果長時間沒有動靜(默認8小時)連接器就會前置斷開連接。被斷開後不能再請求數據了,必須重連才能請求。

show processlist; // 查看當前連接的狀態

在這裏插入圖片描述
儘量使用長連接! 建立連接的過程是比較複雜的,我們要儘量避免這種情況,所以儘量使用長連接。但是全部使用長連接後,有時候MySql佔用內存漲的特別快,因爲連接後我們一直持有連接對象,長期積累內存會大量佔用,只有連接斷開內存才被釋放,或者內存佔用過多被強制殺死(從現象上看是異常重啓了)

解決方案如下:
1.定期斷開重連長連接,這個會釋放內存。
2.每次執行一個比較大的操作後,要執行mysql_reset_connction來初始化連接資源(必須在Mysql5.7以上才行),注意,這不是重連而是將恢復到剛剛連接狀態以釋放資源。

2.查詢緩存
建立連接後,你就可以執行select語句了,執行時候首先會查詢緩存。
如果之前執行過這條語句。這條語句的結果會直接以key-value的形式緩存在內存中。key是查詢的語句,value是結果。如果發現緩存中有這條key,那麼value會被直接返回給客戶端。

如果不在緩存在,就會執行下面操作。執行完畢後的結果會再次存放在緩存中。、、

注意:我們不建議加緩存! 看到這的你一定很奇怪,爲什麼呢?緩存命名很優秀。
要知道,只要這個表有更新,這個表中的所有緩存立刻會被清空。哪個表不會有個更新呢,除非只查的表或者很少寫表用這個當然好。但是其他的情況還是不用爲好,因爲對於更新壓力大的表,緩存的命中率是非常低的,白白浪費資源還用不到!
設置不用緩存的方法:

Vim /etc/my.cnf
port  = 3306
socket = /tempmysql.sock
query_cache_type=0 // Query_cache_type可以是0,1,2,0代表不使用緩存,1代表使用緩存,2代表根據需要使用
query_cache_limit=1048576

也可以顯式的指定使用緩存:

	select SQL_CACHE * from T where ID=10

注意: Mysql 8.0開始直接去掉了緩存功能,也就是說8.0開始就徹底沒有緩存了。
3.分析器
如果沒有命中緩存,那麼就要真正執行sql語句了,首先我們需要知道mysql是要幹什麼,分析器就是對語句進行詞法分析。
還是以 select * from T where ID=10; 這條語句舉例,分析器會對這條語句做如下分析:

1. 識別出 select 、from、 where是關鍵字;表名T,  列ID。
2.  判斷是否這條語句語法是否正確。如果錯誤,直接返回錯誤信息。例如下面錯誤語句:
	elect * from t where ID=1;
	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 a where id =1' at line 1

4.優化器
經過分析器後,Mysql就知道你要做什麼了,接下來需要經過優化器處理了。
優化器的作用如下:

	1.如果有索引的話決定使用哪個索引
	2.如果一個語句中有多表關聯(join),決定各個表的連接順序。例如:
	select * from t1 join t2 using(ID) where t1.c=10 and t2.d=20;
	從t1表中取出c=10的ID值,再根據ID值關聯到t2表,再判斷t2表中是否有d=20的值。
	從t2表中取出d=20的ID值,再根據ID值關聯到t1表,再判斷t2表中是否有c=10的值。
	二種方法結果一樣,但是執行效率不一樣,優化器會決定用哪種方式執行。

5.執行器
分析器告訴你要做什麼,分析器告訴你怎麼做。執行器就是執行語句。
執行前要先判斷是否有權限,如果沒有權限會直接返回錯誤。流程是這樣的:

	第一步:默認取InnoDB引擎接口取表中的第一行,判斷ID是否等於10,如果不是則跳過,如果是則將這一行存在結果集中
	第二步:調用引擎接口取下一行數據,重複第一步的判斷,直到取到最後一行。
	第三步:將結果集(包含所有符合條件的行)返回給客戶端

3.2 存儲引擎層簡單介紹

我們在創建一個表的時候如果不指定,默認是用InnoDB存儲引擎,當然我們也可以自己指定。代碼如下:

		CREATE TABLE study
		(
			id  varchar(40),
		) ENGINE=INNODE DEFAULT ;
  1. InnoDB存儲引擎
    InnoDB是MySql最重要的存儲引擎,沒有之一那種。它是支持事務,如果沒有指定存儲引擎默認的就是使用它,並且在使用Mysql的時候優先考慮它,除非有非常特別的原因。

  2. MyISAM存儲引擎

    MYISam存儲引擎不支持事務和行級鎖,相反MYISAM是表級鎖。
    最大的缺陷就是崩潰後無法安全恢復,這裏指的是崩潰後修復可能有數據的丟失,而且修復特別慢。
    適用於只讀,表比較小等場景。

  3. Archive 引擎
    archive的意思是存檔的意思,所以它僅僅支持插入和查詢操作,
    archive引擎適合日誌和數據採集類的場合。

  4. Memory引擎
    如果需要快速的訪問數據,而且允許一旦斷電後數據的丟失,那麼推薦使用Memory表。Memory表是在內存中工作的,速度非常快,MyISAM跟它簡直不在一個等級上。

3.3 如何選擇合適的引擎

選擇引擎要考慮以下因素:

1.是否要支持事務
2.備份的需求也會影響存儲引擎的選擇。
3.崩潰後是否要完全恢復數據
4.其他特性。

每一種存儲引擎都有各自的應用場合,要視情況而定。

4 結尾

好了,今天就寫到這裏吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章