MySQL優化 二 索引的介紹

2021-08-28 20:48:28 字數 4590 閱讀 7939

索引的作用

1.提高查詢的速度

2.提高排序的速度

3.提高分組的速度

btree型別的索引

內部實際採用二叉樹的資料結構,例如

4

2 6

1 3 5 7

採用類似的資料結構將資料的查詢時間複雜度從n/2降低到log2n

hash型別的索引

採用hash演算法,將每乙個主鍵進行自定義的hash函式從而直接得到資料儲存的位址,因為是直接進行運算得到的位址,不需要進行查詢,所以查詢時間複雜度為(

優點

快(適用於精準查詢)

缺點

1.因為是隨機放置資料,所以容易引起記憶體空洞

2.因為是對某乙個主鍵進行hash函式的運算,可能在精準查詢的時候很快,但是碰到範圍查詢時不能進行優化,例如where id>20

3.無法使用字首索引(具體定義見下文),而btree可是使用字首索引

4.排序無法優化

5.必須進行回行,即hash只能得到位址,所以需要進一步根據位址去取值(btree的聚簇索引不需要)

索引左字首

建立乙個多列索引 a,b,c

語句是否發揮作用

where a = 1

a 發揮作用

where a= 1 and b = 2

a,b發揮作用

where a= 1 and b = 2 and c = 3

a,b,c發揮作用

where b = 1 / where c= 1

無where a= 1 and c = 1

a發揮作用

where a= 1 and b > 10 and c = 1

a,b發揮作用

where a= 1 and b like 「123%」

a,b發揮作用

where a= 1 and b like 「%123」

a發揮作用

因為多列索引具有順序性和左字首性

例如 a,b,c是一根完整的管道,當沒有b時只有a能用,c是斷的所以不能用

當只有b,c或者只有b只有c時,因為坐字首性,因為左邊沒有a所以整根管道處於斷路,都不能用

當b為"123%「時,因為左邊為確認值,所以b能部分使用,但是處於b後面的都不能用

當b為」%123"時,因為左邊為不確認值,所以b不能使用,所以b以及處於b後面的都不能用

經典索引題

現有a,b,c,d四列,將a,b,c三列建立索引

語句是否發揮作用

備註where a =1 and b = 1 and d >8 and c = 1

a b c都能起作用

雖然語義上不符左字首,但是mysql會自動優化

where a =1 and b = 1 and d >8 order by c

a b c都能起作用

ab作用於查詢,c用於排序

where a =1 and d >8 order by c,b

a都能起作用

a作用於查詢,bc雖然建立索引但是順序不符合左字首

where a =1 and d >8 order by b,c

a,b,c都能起作用

a作用於查詢,bc用於排序

where a =1 and b = 2 order by b,c

a,b,c都能起作用

a,b作用於查詢,c用於排序

二級索引

一般為多列的索引,其無論主鍵索引是聚簇索引還是非聚簇索引,其存放的資料僅為指向主鍵的位置的指標,即指向主鍵

索引覆蓋

當查詢的內容就是索引的一部分時,就不會產生回行現象,查詢速度較快

例如 表test建立了a,b的聯合索引

select a from test where a = 1 and b = 3;(快)

select c from test where a = 1 and b = 3;(慢)

聚簇索引(innerdb)

雖然採用二叉樹的資料結構,但是葉子不僅儲存資料的位址還儲存實際資料

4[索引|實際資料] 

2[索引|實際資料] 6[索引|實際資料]

1[索引|實際資料] 3[索引|實際資料] 5[索引|實際資料] 7[索引|實際資料]

優點

1.查詢速度較快

因為索引與資料存放在一起,所以不存在回行現象,所以查詢速度較快

2.排序速度較快

因為索引與資料存放在一起,所以不存在回行現象,所以可以避免fielsort操作,排序速度較快

2.當亂序插入資料的時候,結果依然有序(非聚簇索引不一定)

當聚簇索引插入資料,當生成索引樹的時候,因為聚簇索引索引與資料存放在一起,因為索引是根據二叉樹有序的,所以資料也是有序的,而非聚簇索引,因為索引樹只存放相關實際資料的位址,所以亂序存放時並不會自動排序

缺點

當插入順序不規律時,會形成頁**現象,速度會比非聚簇索引稍慢

因為葉子儲存索引與所有的資料,所以葉子較重,當插入順序不規律時,因為要生成二叉樹時,因為葉子較重,速度會比較慢(使用固態硬碟會有所緩解)

經典樣例

例如乙個innerdb的表test,定義了,a,b,c三列,其中c為text的超長列,a為主鍵,再定義a,b為乙個索引

select * from test order by a;(很慢)

select * from test order by a ,b;(很快)

關鍵原因如下

1.儲存引擎為innerdb(使用聚簇索引),如果使用非聚簇索引則查詢速度一致

2.使用的索引為主鍵索引,因為有大資料列存在所以,主鍵索引樹較重所以速度較慢

3.有大資料列c存在,如果沒有大資料列,查詢速度相差不大

雖然a建立了主鍵索引,但是因為是聚簇索引,所以主鍵a會與大資料c一起放在一棵索引樹內,會非常重,而二級索引a,b則是另乙個索引樹,存放資料僅為主鍵的位址,所以查詢速度會比主鍵還快,所以建議合理建立索引,合理使用索引

非聚簇索引(myisam)

雖然採用二叉樹的資料結構,但是葉子不僅儲存資料的位址還儲存實際資料

內部實際採用二叉樹的資料結構,例如

4[索引]

2[索引] 6[索引]

1[索引] 3[索引] 5[索引] 7[索引]

利用索引進行排序

一.排序的資料是索引的一部分

發生索引覆蓋,速度很快

二.排序的資料與是索引無關

這個時候mysql會將資料取出形成乙個臨時表,然後進行filesort(可能會在磁碟上進行)

在非聚簇索引中,雖然可以根據有序的索引去一邊取索引一邊取資料,這樣取出的資料雖然也是有序的.

但是因為頻繁的回行效率很低,所以非聚簇索引的資料庫引擎會先把所有的資料取出然後對資料直接進行排序,

因為可能會在磁碟上進行,所以速度可想而知,我們應該盡可能的去避免filesort

我們需要爭取去資料庫取出的資料就是有序的(利用索引進行排序)

當sql語句的查詢操作使用的索引與排序操作的索引不一致時,雖然兩個操作都使用了索引,但是還是會產生filesort,

例,test表有cat_id與good_id這兩個單列索引

select * from test where cat_id > 10 order by good_id;(使用filesort)

select * from test where good_id > 10 order by good_id;(未使用filesort)

因為當查詢操作使用的索引與排序操作的索引不一致時,根據where查詢出來的語句對order使用的索引依然是無序的,所以還是會產生filesort

Mysql索引使用 索引優化(二)

一 什麼情況下適合使用索引?欄位的數值有唯一性的限制,比如使用者名稱,可以用唯一索引或者主鍵索引 頻繁作為 where 查詢條件的字段,尤其在資料表大的情況下 需要經常 group by 和 order by 的列 索引就是讓資料按照某種順序進行儲存或檢索,因此當我們使用 group by 對資料進...

MySql語句優化以及索引介紹

innodb和myisam 主要是這兩個其他可以忽略 兩者的特點和區別 innodb myisam msyql中的事務隔離級別 首先理解髒讀 不可重複讀和幻讀的含義。髒讀 讀到乙個事務未提交的資料。不可重複讀 事務1讀取了一行資料,但是事務未結束時,事務2對該資料進行修改了,事務1再次讀取時,兩次讀...

Mysql筆記(二)索引介紹

索引介紹 索引是什麼 官方介紹索引是幫助mysql高效獲取資料的資料結構。更通俗的說,資料庫索引好比是一本書前面的目 錄,能加快資料庫的查詢速度。索引的優勢和劣勢 優勢 劣勢 索引的分類 索引的使用 建立索引 create index index name on table column lengt...