最近在讀丁奇大佬的《MySQL實戰45講》,收穫很大,因此準備跟着寫一點筆記總結。java
上面是MySQL的邏輯架構圖,由它可見MySQL大體分爲Sever層和存儲引擎層。mysql
用戶經過SQL訪問數據的基本過程,就是:客戶端-Server層-存儲引擎層-磁盤。web
客戶端經過鏈接器與Sever層相連,SQL語句在Sever層中「暢遊」一番後便知曉了用戶想要幹什麼,而後,執行器操做數據引擎,進行存儲/獲取數據。sql
Server層除了圖中各類「xx器」以外還含有MySQL中全部的內置函數(如:sum(),count()等),全部跨存儲引擎的功能也都存在於此,好比說:存儲過程,觸發器,視圖等。數據庫
存儲引擎主要是:InnoDB、MyISAM、Memory三種,自MySQL5.5.5版本後InnoDB成爲了MySQL的默認存儲引擎。緩存
選擇存儲引擎的SQL語句服務器
create table tableName(id int) engine=innodb;
mysql -h$ip -P$port -u$user -p
輸入以上信息以後,鏈接器會跟服務器創建鏈接,在完成經典的TCP握手後,鏈接器開始經過你輸入的用戶名和密碼來進行身份認證,認證不成功會返回「Access denied for user」的錯誤,認證成功會在權限表中查詢你所擁有的權限,進而給你相應的操做權力。架構
使用 show processlist 命令可以查詢全部的鏈接,Commend這一行出現Sleep就代表這個鏈接處於空閒狀態,若是長時間沒有操做,這個鏈接就將在wait_timeout時間後斷開,這個參數的默認值是8小時。函數
長鏈接是指鏈接成功後,客戶端持續請求都一直使用的一個鏈接叫長鏈接。短鏈接是執行幾回查詢後就斷開的鏈接,下次查詢再從新創建一個鏈接。oop
創建鏈接的過程是複雜的,因此要儘可能少創建鏈接,也就是儘可能使用長鏈接。
若是所有使用長鏈接,MySQL會漲的特別快,有些資源只有再鏈接斷開時才能釋放,可能致使內存佔用太大,被系統強行殺掉,形成MySQL異常重啓。
通常解決這種問題有下面兩個方案:
1.按期斷開長鏈接。使用一段時間,或者程序裏面判斷執行過一個佔用內存的大查詢後,斷開鏈接,以後要查詢再重連。 2,若是你用的是 MySQL 5.7 或更新版本,能夠在每次執行一個比較大的操做後,經過執行 mysql_reset_connection 來從新初始化鏈接資源。這個過程不須要重連和從新作權限驗證,可是會將鏈接恢復到剛剛建立完時的狀態。
MySQL緩存是個很雞肋的東西,已經再MySQL 8.0版本後完全刪除。
MySQL緩存將他的查詢請求的結果放在緩存中,當再次查詢這個語句時從緩存裏直接把以前的結果拿出來,效率就很高,可是表中每增長或修改一次數據都會形成緩存的失效致使維護成本很高。
下面是一個緩存查詢的SQL
mysql> select SQL_CACHE * from T where ID=10;
分析器主要功能就是 處理語法 和 解析查詢,分析SQL中的每個關鍵字,判斷語法是否正確、語句中的表和列是否存在,且select後面的列名有沒有歧義,好比說:user表和type表中都有name字段,那麼select name from use,type是確定經過不了的。
優化器是在表裏面有多個索引的時候,決定使用哪一個索引;或者在一個語句有多表關聯(join)的時候,決定各個表的鏈接順序。
就如下面爲例
select * from t1 join t2 using(ID) where t1.c=10 and t2.d=20;
優化器會根據執行效率的不一樣選擇更優者。其實在這裏面我遇到和考慮了一些問題,主要是SQL語句層面的:
之前,一個同窗跟我講 where 後面的篩選條件的排序很重要,由於where後面的條件是順序執行的,好比說下面一個查詢。
select * from student where sex = '女' and age > 30
從實際狀況來看 age > 30 的學生不多,被篩選掉的可能更高,因此若是按照順序執行的原則來講,講age > 30放在and前面的選擇纔是好的選擇。
可是!當我知道了優化器,我發現我想固然了,MySQL比我想象的更強大,它可以根據實際的狀況來選擇SQL執行的順序
另外,在學習丁奇課程時上面那個例子的解釋讓我又有點迷茫了,是下面這段SQL
select * from t1 join t2 using(ID) where t1.c=10 and t2.d=20;
他說:「既能夠先從表 t1 裏面取出 c=10 的記錄的 ID 值,再根據 ID 值關聯到表 t2,再判斷 t2 裏面 d 的值是否等於 20....」。
我以前一直所認爲的是 t1 與 t2表先鏈接成笛卡爾積以後纔會經過 where 後面的條件進行篩選.
可是!!!
我又想固然了,在網上不少人給的執行順序也是 from > join > on > where ... 的執行順序,可是實際上SQL 中 得join是使用一種爲Nest Loop Join嵌套循環(具體文章請見).
優化器先會選擇驅動表好比說當 t1中c=10的次數少於t2中d=20的次數那麼優化器就會選擇t1作驅動表,而後經過t1.c=10篩選出一行數據再在t2表中查找t2.d=20而且t1.id=t2.id的數據行,遍歷完畢t2後,再從新在t1中查找符合t1.c=10的數據,依次交替,直到查詢玩全部的數據。
進入執行器以後,先要判斷一下你有沒有操做這個表的權限,若是沒有就會返回沒有權限的錯誤,若是有就打開表,去調用存儲引擎的接口。基本流程以下:
數據庫的慢查詢日誌中會有一個rows_examined表明這個SQL語句執行過程當中總共查詢了多少行。