本篇繼續介紹有關索引的使用。
目錄
一、SQL提示
?二、單列索引和聯合索引
三、覆蓋索引
四、前綴索引
?五、索引的使用原則
一、SQL提示
我們在使用索引來進行查詢時,很有可能會出現一個字段中包含多個索引的情況,例如這里有一個name字段,該字段關聯了兩個索引
當我們根據這個字段進行查詢時,這兩個索引都有可能會用到?那為什么最后用了i_n_g這個索引呢?這是MySQL替我們選擇的,那可不可以指定使用哪個索引呢?其實是可以的,我們只需要在查詢時給MySQL一個提示,讓其使用某個索引,但這僅僅只是提示,具體使用哪個索引,還需要MySQL自行進行評估選擇。
下面我們再來進行一次前面的查詢語句,并提示MySQL要使用?i_u_n這個索引
語法如下:
select 字段名 from 表名 use index(要使用的索引名) 查詢條件
我們還可以提示MySQL要忽略某個索引,具體如下:
select 字段名 from 表名 ignore?index(要忽略的索引名) 查詢條件
?
我們也可以強制MySQL使用某個索引?,具體如下:
select 字段名 from 表名 force?index(要強制使用的索引名) 查詢條件
?二、單列索引和聯合索引
在MySQL中,我們可以根據單個字段構建索引(單列索引),也可以根據多個字段共同創建索引。單列索引的結構為B+Tree,并根據這單個字段的值進行大小比較。
聯合索引同樣為B+Tree結構,它會先根據最左邊的字段來建樹,如果最左邊的字段值相同,則會以后一個字段值進行比較,以此類推。
?
三、覆蓋索引
前面的文章中我們介紹過索引可以根據存儲方式?的不同分為聚集索引和二級索引,聚集索引的葉子節點中包含一整條記錄,而葉子節點的值則只包含索引的字段和主鍵字段的值。因此,在使用二級索引來進行查詢時,如果查詢的字段不只有索引的字段和主鍵的字段,那么將會進行回表操作,但如果查詢的字段包括在索引的字段和主鍵的字段里,那么將不會回表,直接就能返回查詢結果,此時使用的索引就可以稱之為覆蓋索引。
例如,下面這條SQL
(該表包含id,name,age三個字段)?
可以發現,這條SQL查詢的字段除了索引的字段(name)和主鍵的字段(id)外,還有一個age字段,因此,該次查詢回表了,該索引也就不是覆蓋索引。
我們通過profile來查看一下此次查詢的時間
接下來我們再刪掉name字段的索引,然后再根據name和age字段來創建一個聯合索引?
此時我們再進行前面的查詢語句,然后再通過profile查看一下執行時間?
?
可以發現這次查詢要更快一點,這是因為查詢的字段全部包含在聯合索引和主鍵的字段里了,此次次使用的索引為覆蓋索引,不再回表了。因此,我們還可以得出一個經驗:當查詢的字段比較多時,盡量創建聯合索引來形成覆蓋索引,從而避免回表操作,增強查詢的效率。
四、前綴索引
當我們對字符串類型的字段創建索引時,需要對該字段的值進行比較,而字符串的比較,需要比較字符串中的字符,如果字符串比較長的話,那么比較的時間就會比較長,例如“hello,word”和“hello,words”需要比較10次才能比較出結果,這樣就會導致比較所消耗的時間較長,影響查詢的性能,因此我們可以選擇只取該字符串的前綴來進行比較,這樣就能讓比較消耗的性能更少一點。像這種只比較字符串前綴創建的索引就為前綴索引,下面我們來看一下如何創建前綴索引。
創建前綴索引的語法如下:
create index? 索引名 on 表名(字段名(前綴長度))?
這里有一個name字段?,我們給它加上一個前綴索引:
此時,我們就給name字段創建好長度為5的前綴索引了。
?這個前綴長度要怎么確定呢?我們可以枚舉前綴的長度,并查看該長度的不重復的前綴占全部記錄的比值,如果該比值在某個值以上就可以以該長度作為前綴長度,例如,我們以1作為前綴長度,然后我們通過MySQL查詢比值,???????
可以發現這個比值較低,因此1不適合作為前綴長度?,我們再來看一下2作為前綴長度
此時比值達到了1因此2適合作為前綴長度。?
?五、索引的使用原則
索引的使用會大大提升我們的查詢效率,但索引并不是一定會生效,會有索引失效的情況場景出現,同時,索引也不一定就能提升查詢效率,有時甚至還會降低我們的查詢效率,因此正確的使用索引是尤為重要的,,下面我們來看一下索引使用時應遵循的原則。
- 創建索引的表的數據量盡可能多,且該表的查詢操作占比要大于修改操作的占比。
- 對需要進行查詢,排序,分組等操作的字段創建索引。
- 如果字段為字符串類型,應盡量根據情況創建前綴索引。
- 查詢的字段多時,盡量創建聯合索引,從而做到覆蓋索引。
- 索引的數量不是越多越好,應當根據需求創建索引,不要不需要索引的字段也創建索引了
- 如果索引的字段不能存放null值,盡量再建表時對該字段進行not null約束,當MySQL知道哪個字段不含NULL值時,能夠更好的確定使用哪個索引性能更好。
?