1. 程式人生 > >MySQL的B+Tree索引

MySQL的B+Tree索引

為什麼要使用索引?

最簡單的方式實現資料查詢:全表掃描,即將整張表的資料全部或者分批次載入進記憶體,由於儲存的最小單位是塊或者頁,它們是由多行資料組成,然後逐塊逐塊或者逐頁逐頁地查詢,這樣查詢的速度非常慢。優點:在資料量小比如只有幾十行資料的情況下很快。但資料量大時不適用。更通常情況下,我們應該避免全表掃描,我們可以通過索引來大幅提升查詢資料的速度。

什麼資訊能夠成為索引?

能把記錄限制在一定查詢範圍內的欄位,比如鍵,唯一鍵,主鍵等

B+ Tree更適合用來做索引原因:

1.B+ 樹的磁碟讀寫代價更低。因為它的非葉子節點只儲存索引而不儲存具體資料,因此其內部節點相對B Tree 更小。如果把所有內部節點的關鍵字存放在同一盤塊中,這個盤塊能容納的關鍵字數量就更多,一次性讀入記憶體中的需要查詢的關鍵字也越多,相對來說,I/O次數就降低了。

2.B+ 樹查詢效率更加穩定。其內部節點並不是最終指向檔案內容的節點,而只是葉子節點中關鍵字的索引,所以任何關鍵字的查詢必定有一條從根節點到葉子節點的路徑。所以關鍵字查詢的長度相同,導致每個資料的查詢效率也幾乎是相同的穩定的,都是0log(n)

  1. B+ 樹更有利於對資料庫的掃描。B+ 樹只需要遍歷葉子節點就可以對全部關鍵字資訊的掃描,在做範圍查詢時效率很高。

如何優化索引?

1.雜湊索引

缺點:

①僅僅能滿足“=”,“IN",不能使用範圍查詢。雜湊索引比較的是進行雜湊運算之後的雜湊值,所以它只能用於等值的過濾,不能用於基於範圍的查詢,因為經過雜湊運算之後的雜湊值不能保證和原來的鍵值一樣

②無法被用來避免資料的排序操作。由於雜湊索引儲存的是經過雜湊運算之後的值,而且雜湊值不一定和原來的鍵值一樣,所以資料庫無法利用索引的資料來避免任何排序運算。

③不能利用部分索引鍵查詢。

④不能避免表掃描。雜湊索引是將索引鍵通過雜湊運算之後的雜湊值和對應的行指標資訊存放在一個bucket當中,由於不同的索引建會出現相同的雜湊值,所以即使取出滿足某個雜湊鍵值的那些資料,也無法從雜湊索引中直接完成查詢,還是要通過訪問bucket中的實際資料進行相應的比較。

⑤遇到大量Hash值相等的情況後效能並不一定就會比B樹索引高。極端情況下所有資料可能插入到一個桶中,如果正好要查詢最後一條資料,就變成線性的了。

2.BitMap

缺點:只適用於固定欄位的值,而且鎖的粒度非常大,不適用於併發場景,OLAP而不是OLTP

密集索引和稀疏索引的區別?

如何定位並優化慢查詢sql?

  • 根據慢日誌定位慢查詢sql
  • 使用explain等工具分析sql
  • 修改sql或者儘量讓sql走索引

type關鍵欄位:如果出現了all欄位,則表示進行了全表掃描,效率非常低。

最左匹配原則

MySQL中的索引可以以一定順序引用多列,這種索引叫作聯合索引。如User表的name和city加聯合索引就是(name,city),而最左字首原則指的是,如果查詢的時候查詢條件精確匹配索引的左邊連續一列或幾列,則此列就可以被用到。如果查詢條件為後面的一列或幾列,則無法用到此索引。如下:

select * from user where name=xx and city=xx ; //可以命中索引
select * from user where name=xx ; // 可以命中索引
select * from user where city=xx ; // 無法命中索引 

通常讓選擇性最強的索引列放在前面。

索引的選擇性是指:不重複的索引值和記錄總數的比值。最大值為 1,此時每個記錄都有唯一的索引與其對應。選擇性越高,每個記錄的區分度越高,查詢效率也越高。

最左匹配原則的成因?

mysql建立聯合索引的規則是首先對聯合索引最左邊的索引欄位的資料進行排序,然後在此基礎上在對第二個索引進行排序,類似於“order by 欄位1,order by 欄位2,.......”。第一個欄位絕對有序,第二個欄位就是無序的了。因此通常情況下,直接使用第二個欄位條件判斷是用不到索引的。

索引是建立的越多越好嗎?

  • 資料量小的表不需要建立索引。建立索引會增加額外的索引開銷
  • 資料變更需要維護索引,因此更多的索引意味著更多的成本
  • 更多的索引意味著也需要更多的空間

索引的優點

  • 大大減少了伺服器需要掃描的資料行數
  • 可以讓伺服器避免進行排序和分組,以及避免建立臨時表(B+Tree索引本身就是有序的,可以用於ORDER BY和GROUP BY操作。臨時表主要是在排序和分組過程中建立,不需要排序和分組,也就不需要建立臨時表)
  • 將隨機 I/O 變為順序 I/O(B+Tree 索引是有序的,會將相鄰的資料都儲存在一起)

索引的使用條件

  • 對於非常小的表、大部分情況下簡單的全表掃描比建立索引更高效;
  • 對於中到大型的表,索引就非常有效;
  • 但是對於特大型的表,建立和維護索引的代價將會隨之增長。這種情況下,需要用到一種技術可以直接區分出需要查詢的一組資料,而不是一條記錄一條記錄地匹配,例如可以使用分割槽技術。