mysql索引基本原理
阿新 • • 發佈:2021-10-07
mysql整體架構:client層——>server層——>儲存引擎
- client向server層傳送SQL語句,server層通過聯結器接收
- server層的分析器對SQL語句進行語法分析,轉變為AST抽象語法樹
- server層使用優化器對語句中具體查詢的資料
- RBO:基於規則的優化
- CBO:基於成本優化
- 執行器與儲存引擎進行IO互動,獲取查詢結果
- 減少IO次數
- 減少IO量
- 區域性性原理:資料和程式都有聚整合群的傾向,同事之前訪問過的資料很可能再次查詢。
-
磁碟預讀:記憶體跟磁碟在發生資料互動的時候,一般情況下有一個最小的邏輯單元,即"頁
- OLAP與OLTP
- OLAP:聯機分析處理:對海量歷史資料進行分析,產生決策性的影響(資料倉庫——Hive等)
- OLTP:聯機事務處理:要求在很短的時效內返回對應的結果(資料庫——關係型資料庫)
- B+樹
- 每個關鍵字對應一棵子樹
- 每個結點關鍵字個數n的範圍是[m/2]<=n<=m
- 葉節點是包含資訊的,其他所有非葉節點僅起到索引作用,包含了對應子樹的最大關鍵字和指向該子樹的指標
- key:唯一標識,也就是實際資料行中儲存的值
- 檔案地址(offset):偏移量
- Mysql索引系統的資料結構採用3~4層的B+樹,這個層數是由具體磁碟計算出來的。3~4層的B+樹就可以存放千萬級的資料,如果還需存放則需要擴容加表。
- B+樹的最底層即葉子節點是所有的資料,它形成了一個雙向連結串列,用於對主鍵的範圍查詢和分頁查詢。因此B+樹有兩種查詢運算,還有一種就是正常的從根節點隨機查詢
- 在一個磁碟塊中,指標大小是固定的,因此當選擇某欄位當索引時,應該儘量減小鍵值所佔用的空間,這樣可以指數級地增加用於存放資料的空間
- hash:雜湊衝突;範圍查詢時需逐個遍歷;對於記憶體空間要求高。mysql中也存在hash,即memory引擎使用的是hash索引,innodb支援自適應hash,即系統根據資料型別判斷使用哪種儲存結構
- 樹
- 二叉樹:無序
- BST:二叉查詢樹:插入時有序,左子樹小於子樹根節點,右子樹大於子樹根節點
- 插入連續值時,可能退化成連結串列,時間複雜度提高
- AVL:平衡二叉查詢樹:有序,為了解決連續值退化的問題,通過左旋或右旋讓樹平衡,保持最短子樹和最長子樹高度不能超過1
- 通過插入效能的損失來彌補查詢效能的提升
- 紅黑樹:在旋轉平衡的基礎上,新增變色的行為。保持最長子樹不超過最短子樹的2倍即可。使得查詢效能和插入效能近似一致
- 隨著資料的插入,樹的深度越來越深,意味著IO次數越多,影響資料讀取的效率,因此使用開始使用樹
- B樹:多岔樹,有序,非葉子節點也是儲存著資料的,佔用空間較大
- B+樹:多岔樹,有序,只有葉子節點儲存著資料,非葉子節點儲存的是指標
- .frm:存放表結構
- .MYD和.MYI:引擎是myisam,非聚簇索引。
- .MYD:資料,Data
- .MYI:索引,index
- .ibd:儲存資料+索引,即引擎是innodb。只能有一個聚簇索引,可以有很多非聚簇索引。在插入資料時,必須要包含一個索引的key值。這個索引的key值可以是主鍵;若沒有主鍵也可以是唯一鍵;若唯一鍵也沒有,就會有一個自生成的6位元組的rowid(對使用者不可見)
- 定義:根據普通索引查詢到聚簇索引的key值之後,再根據key值在聚簇索引中獲取所有行記錄
- 注:面試常問——在設定主鍵時是否需要自增?答:在滿足業務需求的情況下,能自增儘量自增。因為自增是累加的,對前面的資料沒有影響,無需做插入操作,也就無需做磁碟塊/頁分裂的操作(當在一頁資料裡插入資料時,如果資料滿了就需要分裂成多個頁或者磁碟塊來儲存,父親節點也可能需要分裂,而分裂會影響效率)。追加的效率較高
- select * fro table where name=? and age=? 允許使用
- select * fro table where name=? 允許使用
- select * fro table where age=? 無法使用
- select * fro table where age=? and name=? 允許使用
- 只要查詢條件是組合索引,那麼就算順序相反,mysql內部的優化器會調整對應的順序
- 開啟profiling:set profiling=1;
- 執行SQL語句,然後show profiles; 即可查出上條語句執行的實際時間
- 想要查詢profiles結果表中具體某條語句的所有狀態耗費時長,或者想查詢某條語句的某個狀態的使用情況,根據可使用profiles表語句對應的Query_ID來查詢,語法如下:show profile for [type] query [id]。但這種查詢方式在未來版本可能會被其他工具所取代