mysql之索引組織表


 1.二叉樹/平衡樹.B-tree.B+tree.B*tree

:最上一層是根節點.最底下一層是葉子節點.(一般左邊節點小於右邊節點)

二叉樹:每個節點最多只能有兩個分支,一般只用於教材.二叉樹的深度不可控,造成遍歷數據時IO次數不可控.數據量大了,樹的深度會太大.

二叉樹的變種:BTREE(又寫成B-tree),B+treeB*tree.

B-treebalance-tree:平衡樹:假設1個節點的子節點是5,平衡樹是必須上層節點都滿了,才可加到下層.這樣樹的深度就得到了控制.B-tree除了在葉子節點保存數據,在非葉子節點也保存數據.

B+tree:所有數據都存儲在葉子節點,非葉子節點不存儲數據.且葉子節點間構成了雙向鏈表Mysql用的方法是B+tree.

b+tree的插入必須要保證插入后,葉子節點的數據依然有序。而且不管怎么變化,根節點到葉子節點的深度始終是相同的。

B*tree:也只在葉子節點存儲數據並構成雙向指針,但在非葉子節點有雙向指針

 2.聚簇索引表(索引組織表cluster-index)

在建表時,innodb將表結構數據,存儲在一個B+TREE,B+TREE叫聚簇索引(cluster-index).以聚簇索引構建的表叫聚簇索引表,又稱索引組織表聚集索引頁的葉子節點匯總存放着完整的記錄,副主索引頁中存放着指向葉子的指針。
聚集索引是通過將表的主鍵作為鍵值來構造B+樹的,因為innoDB存儲引擎是通過主鍵來構造的,所以這需要每一張表都有主鍵,如果沒有顯式的指定主鍵,那么數據庫是自動創建主鍵,聚集索引不僅僅包含索引的鍵值,還包含了記錄所在其他列的值,聚集索引中的記錄是根據鍵值順序排列的,但是不是物理排序,而是順序排序。
說明:

1.根據主鍵尋址速度很快

2.主鍵值遞增的insert插入效率較好

3.主鍵值隨機insert插入操作效率差

建議:innodb表必須指定主鍵,最好使用自增數字;

       1.聚簇索引構建規則

1.存在主鍵的情況下,是用主鍵來構建聚簇索引.

2.在沒有主鍵的情況下,如果有唯一性非空索引,就用該索引構建.

3.都沒有,則開辟一個6字節的隱藏列,用隱藏列構建主鍵索引.

   2.聚簇索引的特點:

1. MySQL的表結構由聚簇索引來構建,表結構本身就是索引的一部分。

2.通過表的主鍵來鍵值來構造B+TREE,因為INNODB存儲引擎是一個索引組織表,這意味着每張表都有一個主鍵,如果沒有顯示的創建,則innodb會創建一個六個字節的主鍵,聚簇索引不僅僅包含索引的鍵值,還包含了記錄其他列的信息。

3.聚簇索引是根據鍵值順序存放的,然而要特別注意的是這個順序是指邏輯順序,而不是物理上的存儲順序。因為如果是物理順序那么排序開銷是不被接受的。

4.聚簇索引的非葉子結點存儲的是<</font>鍵值,地址>對。地址為指向下一層的指針,innoDB存儲引擎通過頁在表空間中的偏移量來表示。

5.創建表如果指定主鍵,那么會自動以指定的主鍵進行查詢,互聯網業務中,大多數的OLTP業務中,都是根據主鍵來查詢數據,同時查詢速度也是非常快的。

   3.行數據庫表的兩大類(索引組織表和堆表)

索引組織表(聚簇索引表)>MySQL默認表結構:表本身就是一個索引,數據按照主鍵的順序來進行組織。
堆表(普通的堆表,數據塊構成)—>ORACLE默認表結構(ORACLE也支持索引組織表,但是默認ORACLE的主鍵會默認創建索引)插入數據是隨機的

  4.聚簇索引葉子節點塊

1.數據頁讀取到內存,所以對頁的操作,首先是在內存中操作的,那么就造成一個問題,某一時間,內存和硬盤的數據頁數據不一樣,這是通過事務ACID來可以保證,某一個時間點兩者的數據會到達最終一致性.
2.數據頁在磁盤或者內存空間中,是一次性開辟的,里面的記錄是順序線性存放的(邏輯上的)
3.葉記錄是根據主鍵順序排列的,這個順序是邏輯上的。

  5.數據頁定位數據記錄的過程

在非葉子節點查找數據到葉子節點后,並無法定位數據,在數據頁中有一部分叫做page directory,該部分記錄了每個數據目錄在數據頁中的偏移量,知道偏移量后,進行二分法查找,就可以找到了具體的數據記錄.


      6.索引優點與缺點

索引優點:
1.加快數據檢索效率;

2.可以創建唯一性約束索引,保證數據庫表中每一行數據的唯一性;

3.加速表和表連接效率;

4.在使用分組和排序子句進行數據檢索時,可以顯著減少查詢中分組和排序的時間。

說明:

1.索引可以優化DML操作的查詢部分。

2. 索引提供了查詢的可控性,全表查詢IO不可控。

3. 索引查詢一條數據的IO次數由索引的層數決定

索引缺點:

1.索引需要占用更多物理存儲空間。

2.當對表中的數據進行增加、刪除和修改的時候,索引也要更新維護,降低了數據維護效率

說明:1.盡量在表里不要有冗余索引。2.大數據入庫時,可以先干掉索引,插入數據,然后重建索引。

  7.索引分類

邏輯上: Single column indexes單列索引

Combined IndexesMultiple-Column Indexes 多列索引

Unique 唯一索引     NonUnique 非唯一索引

物理上: clustered index 聚簇索引       not-clustered index非聚簇索引

復合索引:(建立在多個列上的索引)

    8.哪些情況下建議創建索引:

 · 經常需要搜索的列             · 作為主鍵的列,有唯一約束索引

· 經常用在表連接的列  · 經常需要排序的列    · 經常使用在WHERE子句中的列

 

3.助索引

輔助索引又稱二級索引或非聚簇索引.

    1.輔助索引存放的信息

輔助索引也是B+tree,葉子節點存放的是索引列和主鍵值,不存放其他列信息.若無主鍵,則存放的是索引列和該表聚簇索引的虛擬主鍵值.輔助索引是根據索引列的值排序.

    2.聚簇索引和輔助索引的選擇

1. 在聚簇索引和輔助索引都存在的時候,優化器傾向於使用聚簇索引,因為聚簇索引可以通過葉子節點找到數據。

2. 通過輔助索引查詢記錄僅僅只能得到主鍵值,要查詢完整的記錄,還需要通過一次聚簇索引查詢。(回表)

3. 僅僅當主鍵值發生改變的時候,需要更新輔助索引。(問題:索引列改變了難道不更新?)

4. 聚簇索引通常比輔助索引的高度要高(輔助索引不保存所有記錄,更小,高度更低)。

 

4.索引覆蓋、回表與復合索引

           1.覆蓋索引

覆蓋索引:只需通過輔助索引就可以返回數據。
一個查詢語句的執行只需要從輔助索引中就可以得到查詢記錄,而不需要查詢聚集索引中的記錄。也可以稱之為實現了索引覆蓋。特高頻SQL,強烈推薦使用覆蓋索引,可以非常大的提高查詢效率

    2.回表

 指當通過輔助索引查詢得到的記錄信息不足,需要回表再通過聚簇索引查詢信息.

    3.復合索引

復合索引:建立在多個列上的索引..

關於復合索引的使用:遵從最左前綴原則。如當復合索引列有3個時,where條件里是1或者1、2或者1、 2、 3或者1、3時才可用到復合索引.其他查詢都不會用到復合索引

         4.mysql的ICP(索引下推)和對where中過濾條件的處理

ICP:Index Condition Pushdown(索引下推)

ICP技術是在MySQL5.6中引入的一種索引優化技術。它能減少在使用二級索引過濾where條件時的回表次數和減少MySQL server層和引擎層的交互次數。在索引組織表中,使用二級索引進行回表的代價相比堆表中是要高一些的。

當關閉ICP,index 僅僅是data access 的一種訪問方式,存儲引擎通過索引回表獲取的數據會傳遞到MySQL Server層進行where條件過濾。

當打開ICP,如果部分where條件能使用索引中的字段,MySQL Server 會把這部分下推到引擎層,可以利用index過濾的where條件在存儲引擎層進行數據過濾,而非將所有通過index access的結果傳遞到MySQL server層進行where過濾.

優化效果:ICP能減少引擎層訪問基表的次數和MySQL Server 訪問存儲引擎的次數,減少io次數,提高查詢語句性能.

where中過濾條件的處理,根據索引使用情況分成了三種:index key, index filter, table filter

1. index key----確定查詢范圍

用於確定SQL查詢在索引中的連續范圍(起始范圍+結束范圍)的查詢條件,被稱之為Index Key。由於一個范圍,至少包含一個起始與一個終止,因此Index Key也被拆分為Index First KeyIndex Last Key,分別用於定位索引查找的起始,以及索引查詢的終止條件。也就是說根據索引來確定掃描的范圍。

2. index filter---索引過濾

在使用 index key 確定了起始范圍和介紹范圍之后,在此范圍之內,還有一些記錄不符合where 條件,如果這些條件可以使用索引進行過濾,那么就是index filter。也就是說用索引來進行where條件過濾。

3. table filter---條件過濾

where中的條件不能使用索引進行處理的,只能訪問table,進行條件過濾了。也就是說各種各樣的 where 條件,在進行處理時,分成了上面三種情況,一種條件會使用索引確定掃描的范圍;一種條件可以在索引中進行過濾;一種必須回表進行過濾;所以所謂的 ICP 技術,其實就是 index filter 技術而已。只不過因為MySQL的架構原因,分成了server層和引擎層,才有所謂的“下推”的說法。所以ICP其實就是實現了index filter技術,將原來的在server層進行的table filter中可以進行index filter的部分,在引擎層面使用index filter進行處理,不再需要回表進行table filter

     5.索引添加刪除語句

添加聚簇索引: alter table t1 add primary key (id);   ---設置id為主鍵

添加輔助索引:  alter table t1 add index idx_name (name); ---索引名為idx_name

刪除索引:  drop index in_a on t1;

   6.索引掃描說明

在語句前加上explain.查看使用哪個索引.key字段的值為使用的索引名,rows字段的值為查詢過程中掃描到的數據的行數.最后的Extra若是Using index,則說明是走覆蓋索引.當查詢一條或幾條數據,使用了聚簇索引.keyprimary.

當查詢字段是輔助索引列時,走輔助索引.這種不是通過覆蓋索引,故是先通過輔助索引再回表,通過聚簇索引查找數據. key顯示為輔助索引名稱.Extra顯示為null.

覆蓋索引:Using-index只需通過輔助索引就達到結果.沒有通過聚簇索引,故是覆蓋索引,key為輔助索引名稱,Extra顯示為Using index.

   7.唯一索引說明:

 唯一(具有唯一約束的索引,唯一索引):唯一:不能有相同數據

alter table t add unique idx_t1(name).

添加唯一索引時,若該列值有重復,則不能添加.添加成功后,則該列有了唯一約束.

  8.索引的可選擇性

索引選擇性越高,索引的價值越高 索引可選擇性的計算: show index from t1;

后會有一行Cardinality,是不重復記錄的預估值(對列去重)。

使用Cardinality/rows就可以得到可選擇率,越接近1,索引越高效,其值介於(0,1]

舉例:

1. 字段‘gender’,可能有‘男’,‘女’,‘其他’三個值,索引的選擇性為 3/1000 = 0.003

2. 字段id,每條記錄都不同,索引選擇性為1000/1000 = 1

那么查詢id123456gender為‘女’的記錄時應該使用哪個索引?

顯然應該使用id字段上的索引,只要定位到這條索引記錄,就可以立刻確定是否存在這條記錄,然后再驗證性別是否為‘女’,而使用‘gender’字段上的索引,可能需要遍歷多條記錄,對比id后才能確定是否存在這條記錄. 再舉一個極端的情況:如果上述表中所有記錄的‘gender’字段都為‘女’,那么索引的選擇性為1/1000 = 0.001,這時使用‘gender’字段上的索引和全表掃描沒啥兩樣

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM