索引:若索引太多,應用程式的效能可能會受到影響。而索引太少,對查詢效能又會產生影響innodb儲存引擎支援以下幾種常見的索引:
b+樹索引
全文索引
雜湊索引
innodb儲存引擎支援的雜湊索引是自適應的,innodb儲存引擎會根據表的使用情況自動為表生成雜湊索引,不能人為干預是否在一張表中生成雜湊索引。
b+樹索引並不能找到乙個給定鍵值的具體行。b+樹索引能找到的只是被查詢資料行所在的頁。將其讀到記憶體中,
查詢具體某乙個記錄:是二分查詢page dictory。
b+樹索引可以分為聚集索引(clustered inex)和輔助索引,聚集索引與輔助索引不同的是,葉子節點存放的是否是一整行的資訊。
聚集索引:
聚集索引的葉子節點也被稱為資料頁。聚集索引的這個特性決定了索引組織表中資料也是索引的一部分。
同b+樹資料結構一樣,每個資料頁都通過乙個雙向鍊錶來進行鏈結。
很多文件會說:聚集索引按照順序物理地儲存資料。但是試想一下,如果聚集索引必須按照特定順序存放物理記錄,則維護成本顯得非常之高。
所以,聚集索引的儲存並不是物理上連續的,而是邏輯上連續的。
輔助索引:
葉子節點並不包含行記錄的全部資料。葉子節點除了包含鍵值以外,每個葉子節點中的索引行中還包含了乙個書籤。
如果在一棵高度為3的輔助索引樹中查詢資料,那需要對這棵輔助索引樹遍歷3次找到指定主鍵,如果聚集索引樹的高度同樣為3,那麼還需要對聚集索引樹進行3次查詢,最終找到乙個完整的行資料所在的頁,因此一共需要6次邏輯io訪問
b+樹索引的**:
b+樹索引頁的**並不總是從頁的中間記錄開始,這樣可能會導致頁空間的浪費。
innodb儲存引擎的page header有以下幾個部分用來儲存插入的順序資訊:
page_last_insert:最後插入記錄的位置。
page_direction:記錄插入的方向。假如新插入的一條記錄的主鍵值比上一條記錄的主鍵值大,我們說這條記錄的插入方向是右邊,反之則是左邊。用來表示最後一條記錄插入方向的狀態就是page_direction。
page_n_direction:假設連續幾次插入新記錄的方向都是一致的,innodbhi把沿著同乙個方向插入記錄的條數記下來,這個條數就用page_n_direction這個狀態表示。當然,如果最後一條記錄的插入方向改變了的話,這個狀態的值會被清零重新統計。
通過這些資訊:innodb決定向左還是向右進行**,同時決定將**點記錄為哪乙個
2、索引的管理
索引的建立和刪除可以通過兩種方法,一種是alter table,另一種是create/drop index。
索引的檢視:show index from tablename
檢視結果:表名、是否是唯一索引、索引名字、cardinality等。
其中cardinality非常關鍵的值,表示索引中唯一值的數目的估計值。cardinality表的行數應盡可能接近1,如果非常小,那麼使用者需要考慮是否可以刪除此索引。
cardinality值非常關鍵,優化器會根據這個值來判斷是否使用這個索引。但是這個值並不是實時更新的,即並非每次索引的更新都會更新該值,因為這樣代價太大了。
如果需要更新索引cardinality的資訊,可以使用analyze table命令。
3、索引的建立和刪除
舊innodb建立索引過程:建立新錶替換原表。
首先建立一張新的臨時表,表結構為通過命令alter table新定義的結構。
然後把原表中資料匯入到臨時表。
接著刪除原表。
最後把臨時表重名為原來的表名。
後來對於輔助索引:建立的時候對錶上s鎖。
主鍵索引的建立和刪除仍然需要臨時表替換。
通過新的alter table語法,使用者可以選擇索引的建立方式:
alter table tbl_name
|add[index_name]
index_type[index_option]…
algorithm[=]
lock[=]
algorithm指定了建立或刪除索引的演算法。copy是建立臨時表,default是預設inplace。即不建立臨時表。
lock部分為索引建立或刪除時對錶新增鎖的情況:none、share(s)、exclusive(x)、default(嘗試n->s->x)
innodb儲存引擎實現online ddl的原理是在執行建立或者刪除操作的同時,將insert、update、delete這類dml操作日誌寫入到乙個快取中。待完成索引建立後再將重做應用到表上,以此達到資料的一致性。
4、cardinality
cardinality值非常關鍵,表示索引中不重覆記錄數量的預估值。
實際應用中,cardinality/n_rows_in_table應盡可能地接近1。如果非常小,那麼使用者需要考慮是否還有必要建立這個索引。
資料庫對於cardinality的統計都是通過取樣(sample)的方法來完成的。
取樣時機:
表中1/16的資料已發生過變化。
stat_modified_counter>2 000 000 000。
取樣方法:
取得b+樹索引中葉子節點的數量,記為a。
隨機取得b+樹索引中的8個葉子節點。統計每個頁不同記錄的個數,即為p1,p2,…,p8。
根據取樣資訊給出cardinality的預估值:cardinality=(p1+p2+…+p8)*a/8。
5、聯合索引,最左原則。
6、覆蓋索引:
innodb儲存引擎支援覆蓋索引(covering index,或稱索引覆蓋),即從輔助索引中就可以得到查詢的記錄,那就將不會再去搜尋聚集索引。
7、優化
a:某些情況下,優化器可能並沒有選擇索引檢視資料,而是通過掃瞄聚集索引,也就是直接進行全表的掃瞄來得到資料。(多發於範圍查詢,join連線的情況下。)
如果要求訪問的資料量很小,則優化器還是會選擇輔助索引,但是當訪問的資料佔整個表中資料的蠻大一部分時(一般是20%左右),優化器會選擇通過聚集索引來查詢資料。因為之前已經提到過,順序讀要遠遠快於離散讀。
b:mrr優化:
好處:mrr使資料訪問變得較為順序。在查詢輔助索引時,首先根據得到的查詢結果,按照主鍵進行排序,並按照主鍵排序的順序進行書籤查詢。
減少緩衝池中頁被替換的次數。
批量處理對鍵值的查詢操作。
過程:將查詢得到的輔助索引鍵值存放於乙個快取中,這時快取中的資料是根據輔助索引鍵值排序的。
將快取中的鍵值根據rowid進行排序。
根據rowid的排序順序來訪問實際的資料檔案。
案例:mrr還可能把某些範圍查詢拆分為鍵值對:where 2c: icp優化
當進行索引查詢時,首先根據索引來查詢記錄,然後再根據where條件來過濾記錄。在支援index condition pushdown後,mysql資料庫會在取出索引的同時,判斷是否可以進行where條件的過濾,也就是將where的部分過濾操作放在了儲存引擎層。
在某些查詢下,可以大大減少上層sql層對記錄的索取。
B樹索引 hash索引
索引是對資料庫表中一列或多列的值進行排序的一種結構,使用索引可快速訪問資料庫表中的特定資訊。對於乙個表中幾百萬行資料來說,如果不使用索引,每次查詢都需要遍歷一遍所有的行,從而找到所需要的資料,平均查詢效率o n 如果使用了索引,在查詢時會先找索引,快速定位到磁碟位置,然後再去讀出該行的資料,效率大大...
mysql在innodb索引下b 樹的高度問題。
b 樹索引介紹 b 樹索引的本質是b 樹在資料庫中的實現。但是b 樹索引有乙個特點是高扇出性,因此在資料庫中,b 樹的高度一般在2到3層。也就是說查詢某一鍵值的記錄,最多隻需要2到3次io開銷。按磁碟每秒100次io來計算,查詢時間只需0.0.2到0.03秒。資料庫中b 樹索引分為聚集索引 clus...
MySQL索引之B 樹索引
b 樹索引是是目前關係型資料庫系統中查詢最為常用和最為有效的索引,b 樹的索引構造類似於二叉樹,根據鍵值 key value 快速找到資料。1 什麼是b 樹?首先,b 樹中的b並不是二叉樹 binary 的意思,這裡的b表示的是blance即平衡的意思。那麼b 樹其實就是平衡查詢樹。其滿足兩個條件 ...