前言
很多人對數(shù)據(jù)庫索引可能都是知其然卻不知其所以然训挡,對索引沒有很深入的理解歧强,在使用過程中也一知半解,導(dǎo)致沒有辦法準確高效地使用索引肤京,甚至存在不少誤用的情況忘分,導(dǎo)致使用索引反而降低了系統(tǒng)的性能。下面就以MySQL索引為對象白修,通過幾篇文章來帶大家好好的學(xué)習(xí)下索引的知識饭庞。
索引的數(shù)據(jù)結(jié)構(gòu)
索引的存儲方式
索引的利弊以及高效使用
索引利弊
在前面的文章,我們學(xué)習(xí)了索引的數(shù)據(jù)結(jié)構(gòu)和存儲方式熬荆,下面再來理解索引的利弊也就能更加容易和清晰了。
索引的好處
a绸狐、提高數(shù)據(jù)檢索的效率侍郭,降低檢索過程中必須要讀取得數(shù)據(jù)量叹坦,降低數(shù)據(jù)庫IO成本。
b、降低數(shù)據(jù)庫的排序成本一睁。因為索引就是對字段數(shù)據(jù)進行排序后存儲的,如果待排序的字段與索引鍵字段一致减江,就在取出數(shù)據(jù)后不用再次排序了褒链,因為通過索引取得的數(shù)據(jù)已滿足排序要求。另外啊终,分組操作是先排序后分組,所以索引同樣可以省略分組的排序操作趟脂,降低內(nèi)存與CPU資源的消耗已卸。
c、唯一性索引可以在數(shù)據(jù)庫層面保證表中數(shù)據(jù)的唯一性愧哟。
索引的弊端
a人芽、索引會增加 增橄抹、刪、改操作所帶來的IO量與調(diào)整索引的計算量疟羹。
b、索引要占用空間,隨著數(shù)據(jù)量的不斷增大力九,索引還會帶來存儲空間的消耗。
接下來我們再來看下如何高效的使用B+索引
索引高效使用
如何正確建立索引列
適合建立索引的列有以下特點:
- 列的值區(qū)分度高,也就是沒有太多相同的值臂寝,區(qū)分度的公式是count(distinct col)/count(*)败徊。例如只有
男
、女
兩個值沪哺,這樣建立起來的索引樹也只有兩個節(jié)點,意義不大。 - 頻繁查詢的列孽惰,索引的目的就是為了加快查詢效率,所以在頻繁查詢的列建立索引的收益最高酝润。如果是不常搜索的列夏块,建立索引了也沒多少機會用上借跪,反而因為需要維護索引歇由,會降低系統(tǒng)的維護速度和增大了空間需求。
- 經(jīng)常排序释牺、分組的列千劈,索引可以有效地加快排序和分組的效率
- 經(jīng)常用于連接的列(主鍵、外鍵)
不應(yīng)該創(chuàng)建索引的的列具有下列特點:
- 數(shù)據(jù)量很少的表遮怜,數(shù)據(jù)很少的表不需要建立索引,數(shù)據(jù)庫一行一行遍歷可能還更快
- 字段的值很大的列,例如text, image類型的字段等不應(yīng)該增加索引。這是因為,這些列的數(shù)據(jù)量大耕蝉,建立起來的索引會很大垒在,導(dǎo)致降低了索引的效率。
- 頻繁增谦铃、刪驹闰、改的列不適合建索引屹培,因為需要頻繁維護索引媒吗,可能得不償失
- 需要參與計算的列不適合作為索引,例如
where a+b=2
或者where from_unixtime(created_at) = ‘xxx’
如何使用好索引
使用規(guī)則
- 獨立的列:索引使用的時候需要是獨立的列乙埃,不能使用表達式和函數(shù)
- 前綴索引:建立聯(lián)合索引的時候把區(qū)分度高的索引放前面
- 遵循最左前綴原則:使用索引的時候甫何,從左側(cè)開始匹配索引。對于單列索引辙喂,例如索引 A,
where A like aa%
可以使用到索引飞盆,而where A like %aa
不會使用索引;對于組合索引,例如索引(A,B,C),where A=xx
赃阀、where A=xx and B=xx
提佣、where A=xx and B=xx%
會使用到索引荤崇,而where B=xx and C=xx
用不到索引 - 優(yōu)先使用組合索引:在需要使用多個列作為條件進行查詢時拌屏,使用組合索引比使用多個單列索引性能更好。例如對于
where A=a and B=b
术荤,使用組合索引(A,B) 只需要查詢一次索引樹倚喂,而如果分開索引要去兩棵樹查詢 - 使用短索引
- 盡量實現(xiàn)覆蓋索引,也就是需要獲取的數(shù)據(jù)在索引里就有了瓣戚,這樣就不需要去再查一次主鍵索引端圈,例如
select A from table where A=a and B=b
- 在使用InnoDB存儲引擎時,如果沒有特別的需要子库,永遠使用一個與業(yè)務(wù)無關(guān)的自增字段作為主鍵舱权。使用自增字段作為主鍵可以讓索引樹插入更加高效,每次插入都是近似順序插入仑嗅。因此每次插入的時候不需要移動已有數(shù)據(jù)宴倍,因此效率很高张症,而且會形成一個緊湊的索引樹結(jié)構(gòu)。而如果使用隨機主鍵如身份證號的話鸵贬,每次插入可能在索引樹的任何一個地方俗他,索引樹需要頻繁的移動,分頁阔逼,最后形成一個不夠緊湊的索引樹結(jié)構(gòu)兆衅,后續(xù)需要通過OPTIMIZE TABLE來重建表并優(yōu)化填充頁面。
索引失效
在下列情況下嗜浮,索引會失效導(dǎo)致全表掃描羡亩,因此我們要盡量避免以下情況出現(xiàn)。
- 用or的條件周伦,如果or其中一個條件列沒有索引夕春,則不會使用索引
- 使用索引的時候不符合最左側(cè)原則
- 存在索引列的數(shù)據(jù)類型隱形轉(zhuǎn)換,則用不上索引专挪,例如列是字符串及志,而在where語句中用了數(shù)字,如
where A=1
- 列使用了表達式或者函數(shù)
- 在where子句中進行null值判斷
- where 子句中使用 != 或 <> 操作符寨腔、NOT IN操作速侈,但<,<=,=迫卢,>,>=,BETWEEN,IN是可以用到索引的
- 表的數(shù)據(jù)量較少倚搬,數(shù)據(jù)庫判斷不使用索引更快
參考資料
《高性能MySQL》
https://blog.csdn.net/apt1203JN/article/details/79587593
https://blog.csdn.net/zk3326312/java/article/details/79377680
https://www.cnblogs.com/shan1393/p/8999622.html
Enjoy it !
如果覺得文章對你有用,可以贊助我喝杯咖啡~
版權(quán)聲明
轉(zhuǎn)載請注明作者和文章出處
作者: X先生
首發(fā)于http://www.reibang.com/p/e916076920ef