MySQL的索引類型和左前綴索引


1.索引類型:

   1.1B-tree索引:

   注:名叫btree索引,大的方面看,都用的是平衡樹,但具體的實現上,各引擎稍有不同,比如,嚴格的說,NDB引擎,使用的是T-tree,但是在MyISAM,Innodb中,默認的使用的是B-tree索引

 但我們抽象一下---B-tree系統,可以理解成為“排好序的快速查找結構”

 1.2hash索引

       在memory表中,默認的是hash索引,hash的理論查詢時間復雜度為O(1)

   那為啥hash的查找如此的搞笑,為什么都不用hash索引?

   答:1.hash函數計算后的結果,是隨機的,如果是在磁盤上放置數據,以主鍵id為例,那么隨着id的增長,id對應的行,在磁盤上隨機的放置。

   2.無法對范圍查詢進行優化。

     3.無法利用前綴索引   比如 在btree, field列的值“hellopworld”,並加索引查詢 xx=helloword,自然可以利用索引, xx=hello,也可以利用索引. (左前綴索引)      

           為hash(‘helloword’),hash(‘hello’),兩者的關系仍為隨機

   4.排序無法進行優化。

   5.必須得回行。就是說,通過索引拿到的數據位置,必須回到表中取出數據。

2.btree索引的常見誤區:

  2.1在where條件常用的列上加上索引。

  例如:where cat_id=3 and price>100;// 查詢第3個欄目,100元以上的商品。

  誤區:cat_id 和price上都加索引

  錯誤:只能用上cat_id或者是price索引,因為都是獨立的索引,同時只能用上1個

  2.2 在多列上建立索引后,查詢那個列,索引都將會發揮作用。

    誤區:在多列索引上,索引發揮作用,需要滿足左前綴需求。

  以index(a,b,c)為例:

語句

索引是否發揮作用

where a=3     是,只是用了a列的索引

Where a=3 and b=5 

,使用了a,b

Where a=3 and b=5 and c=4

,使用了abc

Where b=3  or  where c=4

Where a=3 and c=4

a列能發揮索引,c不能

Where a=3 and b>10 and c=7

A能利用,b能利用, C不能利用

同上,where a=3 and b like ‘xxxx%’ and c=7

A能用,B能用,C不能用

為便於理解假設ABC10米長的木板河面寬30.

全值索引是則木板長10,

Like,左前綴及范圍查詢則木板長6,

 

自己拼接一下,能否過河對岸,就知道索引能否利用上.

如上例中, where a=3 and b>10, and c=7,

A板長10,A列索引發揮作用

A板正常接B, B板索引發揮作用

B板短了,接不到C, C列的索引不發揮作用.

 

 

假設某個表有一個聯合索引(c1,c2,c3,c4)一下——只能使用該聯合索引的c1,c2,c3部分

 

A where c1=x and c2=x and c4>x and c3=x  

 

B where c1=x and c2=x and c4=x order by c3  

 

C where c1=x and c4= x group by c3,c2    

 

D where c1=x and c5=x order by c2,c3     

 

E where c1=x and c2=x and c5=? order by c2,c3

1 create table t4 (
2 c1 tinyint(1) not null default 0,
3 c2 tinyint(1) not null default 0,
4 c3 tinyint(1) not null default 0,
5 c4 tinyint(1) not null default 0,
6 c5 tinyint(1) not null default 0,
7 index c1234(c1,c2,c3,c4)
8 );
9 insert into t4 values (1,3,5,6,7),(2,3,9,8,3),(4,3,2,7,5);

對於A:

c1=x and c2=x and c4>x and c3=x  <==等價==> c1=x and c2=x and c3=x and c4>x

因此 c1,c2,c3,c4都能用上如下:

 

1 mysql> explain select * from t4 where c1=1 and c2=2 and c4>3 and c3=3 \G
2 *************************** 1. row ***************************
3            id: 1
4   select_type: SIMPLE
5         table: t4
6          type: range
7 possible_keys: c1234
8           key: c1234
9       key_len: 4 #可以看出c1,c2,c3,c4索引都用上

 

對於B: select * from t4 where c1=1 and c2=2 and c4=3 order by c3

c1 ,c2索引用上了,c2用到索引的基礎上,c3是排好序的,因此不用額外排序.

c4沒發揮作用.

 

 1 mysql> explain select * from t4 where c1=1 and c2=2 and c4=3 order by c3 \G
 2 *************************** 1. row ***************************
 3            id: 1
 4   select_type: SIMPLE
 5         table: t4
 6          type: ref
 7 possible_keys: c1234
 8           key: c1234
 9       key_len: 2
10           ref: const,const
11          rows: 1
12         Extra: Using where
13 1 row in set (0.00 sec)
14 
15 mysql> explain select * from t4 where c1=1 and c2=2 and c4=3 order by c5 \G
16 *************************** 1. row ***************************
17            id: 1
18   select_type: SIMPLE
19         table: t4
20          type: ref
21 possible_keys: c1234
22           key: c1234
23       key_len: 2
24           ref: const,const
25          rows: 1
26         Extra: Using where; Using filesort
27 1 row in set (0.00 sec)

 

對於 C: 只用到c1索引,因為group by c3,c2的順序無法利用c2,c3索引

 

 1 mysql> explain select * from t4 where c1=1 and c4=2 group by c3,c2 \G
 2 *************************** 1. row ***************************
 3            id: 1
 4   select_type: SIMPLE
 5         table: t4
 6          type: ref
 7 possible_keys: c1234
 8           key: c1234
 9       key_len: 1 #只用到c1,因為先用c3后用c2分組,導致c2,c3索引沒發揮作用
10           ref: const
11          rows: 1
12         Extra: Using where; Using temporary; Using filesort
13 1 row in set (0.00 sec)
14 
15 mysql> explain select * from t4 where c1=1 and c4=2 group by c2,c3 \G
16 *************************** 1. row ***************************
17            id: 1
18   select_type: SIMPLE
19         table: t4
20          type: ref
21 possible_keys: c1234
22           key: c1234
23       key_len: 1
24           ref: const
25          rows: 1
26         Extra: Using where
27 1 row in set (0.00 sec)

 

D語句: C1確定的基礎上,c2是有序的,C2之下C3是有序的,因此c2,c3發揮的排序的作用.因此,沒用到filesort

 

 1 mysql> explain select * from t4 where c1=1 and c5=2 order by c2,c3 \G  
 2 *************************** 1. row ***************************
 3            id: 1
 4   select_type: SIMPLE
 5         table: t4
 6          type: ref
 7 possible_keys: c1234
 8           key: c1234
 9       key_len: 1
10           ref: const
11          rows: 1
12         Extra: Using where
13 1 row in set (0.00 sec)

 

E: 這一句等價與 elect * from t4 where c1=1 and c2=3 and c5=2 order by c3;  因為c2的值既是固定的,參與排序時並不考慮

 

 1 mysql> explain select * from t4 where c1=1 and c2=3 and c5=2 order by c2,c3 \G
 2 *************************** 1. row ***************************
 3            id: 1
 4   select_type: SIMPLE
 5         table: t4
 6          type: ref
 7 possible_keys: c1234
 8           key: c1234
 9       key_len: 2
10           ref: const,const
11          rows: 1
12         Extra: Using where
13 1 row in set (0.00 sec)

 

上面就是一個比較經典的左前綴的匹配案例,因此我們在工作中應該在經常使用的列上加索引。

 


免責聲明!

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



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