mysql 之聯合索引
1.什麼是聯合索引
一般我們使用的是單列索引(B+TREE),但少數情況下也會使用到多列索引,也就是平時的聯合索引,又稱複合索引。
B+TREE的結構如下:
每一個磁碟塊在mysql中是一個頁,頁大小是固定的,mysql innodb的預設的頁大小是16k,每個索引會分配在頁上的數量是由欄位的大小決定。當欄位值的長度越長,每一頁上的數量就會越少,因此在一定資料量的情況下,索引的深度會越深,影響索引的查詢效率。
對於複合索引(多列b+tree,使用多列值組合而成的b+tree索引)。遵循最左側原則,從左到右的使用索引中的欄位,一個查詢可以只使用索引中的一部份,但只能是最左側部分。例如索引是key index (a,b,c). 可以支援a a,b a,b,c 3種組合進行查詢,但不支援 b,c進行查詢。當使用最左側欄位時,索引就十分有效。
2、怎樣使用聯合索引
建立表test如下:
create table test(
a int,
b int,
c int,
KEY a(a,b,c));
比如(a,b,c)的時候,b+數是按照從左到右的順序來建立搜尋樹的,比如當(a=? and b=? and c=?)這樣的資料來檢索的時候,b+樹會優先比較a列來確定下一步的所搜方向,如果a列相同再依次比較b列和c列,最後得到檢索的資料;但當(b=? and c=?)這樣的沒有a列的資料來的時候,b+樹就不知道下一步該查哪個節點,因為建立搜尋樹的時候a列就是第一個比較因子,必須要先根據a列來搜尋才能知道下一步去哪裡查詢。比如當(a=? and c=?)這樣的資料來檢索時,b+樹可以用a列來指定搜尋方向,但下一個欄位b列的缺失,所以只能把a列的資料找到,然後再匹配c列的資料了, 這個是非常重要的性質,即索引的最左匹配特性。以下通過例子分析索引的使用情況,以便於更好的理解聯合索引的查詢方式和使用範圍。
select * from test where a=? and b=? and c=?;查詢效率最高,索引全覆蓋。 select * from test where a=? and b=?;索引覆蓋a和b。 select * from test where b=? and a=?;經過mysql的查詢分析器的優化,索引覆蓋a和b。 select * from test where a=?;索引覆蓋a。 select * from test where b=? and c=?;沒有a列,不走索引,索引失效。 select * from test where c=?;沒有a列,不走索引,索引失效。
二、多列索引在範圍查詢中應用
select * from test where a=? and b between ? and ? and c=?;索引覆蓋a和b,因b列是範圍查詢,因此c列不能走索引。 select * from test where a between ? and ? and b=?;a列走索引,因a列是範圍查詢,因此b列是無法使用索引。 select * from test where a between ? and ? and b between ? and ? and c=?;a列走索引,因a列是範圍查詢,b列是範圍查詢也不能使用索引。
三、多列索引在排序中應用
select * from test where a=? and b=? order by c;a、b、c三列全覆蓋索引,查詢效率最高。 select * from test where a=? and b between ? and ? order by c;a、b列使用索引查詢,因b列是範圍查詢,因此c列不能使用索引,會出現file sort。
四,總結聯合索引的使用在寫where條件的順序無關,mysql查詢分析會進行優化而使用索引。但是減輕查詢分析器的壓力,最好和索引的從左到右的順序一致。使用等值查詢,多列同時查詢,索引會一直傳遞並生效。因此等值查詢效率最好。索引查詢遵循最左側原則。但是遇到範圍查詢列之後的列索引失效。排序也能使用索引,合理使用索引排序,避免出現file sort。