MySQL 簡記
mysql中的數據存儲的結構是B+樹
- 其與B樹的相同點是,B+樹一個節點也可以存放多條數據,并且從左到右依次增大;
- 不同點是,B+樹的葉子結點之間也能相互連接。那么實際上是采取利用空間換區時間的策略。
那么B+樹的樹結構like this:
然后mysql中的數據存儲是這樣的:
其實在mysql里面自增主鍵是要比uuid要好的,原因是因為,當每次插入數據的時候,直接向下、向下一頁去插入就好了;如果說不是自增主鍵,那么當一頁數據存滿,新插入的數據主鍵大小應該是在舊的頁上時,就需要挪動原始的舊數據的最后一個,插入到新的一頁,然后將新插入的數據插入到舊的也里面中,這伴隨著系統的消耗。
可以回答為什么innodb中使用B+樹來存儲,用空間換時間
就是用空間換取時間的效率,假設一頁能存四條數據,那么每一個頁都有一個頁目錄,頁目錄存的是主鍵的索引,每隔幾個一個索引,在利用索引查找的時候,先查找頁目錄,就能快速遍歷一頁的數據,倘若目標主鍵在這一頁的某兩個主鍵索引之中,再從頁目錄那個對應的索引所給的地址跑到用戶數據區域毒地贏得數據,再從中間開始遍歷數據區域,直到找到目標數據。這個時候已經離目標很近的,就很快能走完。
當有很多很多頁的時候,就有一個頭頁,當有很多很多頭頁,就有一個更高的頭頁來建立索引。因此當查詢一個很大的索引例如600000時,不需要從頭數據遍歷到尾,只需要遍歷最頭的頁就清楚了。
注:超級頁就是頭頁,一般兩層的B+樹就好了
innodb是如何支持范圍查找能走索引的?
索引的時候,如果范圍查找select * from table1 where a = 6;
,假設a是主鍵,那么走的是主鍵索引,從頭頁開始從上往下找;如果我搜索的不是主鍵,而是b= 6,那么就是全表掃描,走的是最下面這一層的頁,一頁一頁的走查找b.
innodb里面的一頁是多大?
在數據庫中,一頁是16dkB,計算機操作系統里面一頁時4KB大小。
那么高度為2的B+樹能存多少條數據?
一條數據是包含一個int值和一個指針,那么就是4B+6B = 10B,一個頭頁里面能存A=16KB/10B個頁,然后一個頁里面用B=16KB/一條數據,最后存的數據量就是A*B。
為什么遵循最左前綴原則才能利用索引?
因為創建索引的時候,假如有5個字段,第一個為主鍵,創建中間的三個為一個復合索引,這個其實也就是非聚族索引的一種,它會構建一個B+樹,那么樹的排列,數值的分布都是按照:比較第一個字段,如果第一個字段相同再比較第二個字段,其次再比較第三個字段的形式進行構建樹的,所以必須要遵循最左前綴原則才能利用索引。那么找到了對應的索引之后會進行回表查詢全字段的值。如何能夠回表到對應的數據?是索引里面存了主鍵的值,那么通過主鍵就可以回表找到信息返回
覆蓋索引和索引掃描的底層原理
覆蓋索引就是,復合索引里面包含了要查找的字段,那么這個時候就不用回表查看全字段數據,直接走索引找到需要的索引的字段就好了。
索引掃描是,相比全表掃描,索引掃描里包含了要查找的對應的字段,那么一頁里面包含的數據就會更多,查找的就會更快,所以這個時候,用索引反而更快一些。
mysql里面類型轉換需要注意的
一般是char型的會轉換為int型的,它會直接把字符轉換為數字0
所以explain select * from table1 where a = 0
,如果a是一個int類型的字段,而數據里面有個字符‘c’的話,那么會查找到它,‘c’->0
那么如果是a字段里面存了字符’1’,那么會直接轉成數字’1’
什么情況下會導致索引失效
當直接對字段進行操作,比方說搜索a+1 =1這樣的情況,那么對于數據庫引擎來說,都要先對內存里面的構造的索引B+樹進行更改,例如字段類型是varchar的,對他加了1,那么需要先把所有的字段全部都轉換成數字(字符字母轉換成0,數字‘1’轉換成1),然后再加上1,然后再進行索引查找。這以過程耗費的資源是很大的,
而且還可能會引發問題,可能會破壞B+樹的順序。
那么:一旦對字段進行了操作,那就會導致索引失效,走不了索引
mysql慢查詢如何優化
- 檢查是否走了索引,如果沒有則優化其利用索引
- 檢查所以利用的索引,是否是最優索引
- 檢查所查字段是否都是必須的,是否查詢了過多字段,或者多余數據
- 檢查表中數據是否過多
索引 - 檢查所以利用的索引,是否是最優索引
- 檢查所查字段是否都是必須的,是否查詢了過多字段,或者多余數據
- 檢查表中數據是否過多
- 檢查數據庫實例所在機器的性能配置,