深入浅出MYSQL查询索引失效
深入淺出MYSQL查詢索引失效
mysql索引原理
B+樹
索引優(yōu)缺點
優(yōu)點
- 大大減少了服務(wù)器需要掃描的數(shù)據(jù)量
- 可以幫助服務(wù)器避免排序或減少使用臨時表排序
- 索引可以隨機(jī)I/O變?yōu)轫樞騃/O
缺點
- 需要占用磁盤空間,因此冗余低效的索引將占用大量的磁盤空間
- 降低DML性能,對于數(shù)據(jù)的任意增刪改都需要調(diào)整對應(yīng)的索引,甚至出現(xiàn)索引分裂
- 索引會產(chǎn)生相應(yīng)的碎片,產(chǎn)生維護(hù)開銷
索引失效場景
字符串型字段,比較時用了整形
like的通配符在前
查詢條件中使用了or,但是沒有把or中所有字段加上索引
對索引列進(jìn)行函數(shù)運算
聯(lián)合索引abc問題
Mysql從左到右的使用索引中的字段,一個查詢可以只使用索引中的一部份,但只能是最左側(cè)部分。
例如索引是index (a,b,c),可以支持a | a,b| a,b,c 3種組合進(jìn)行查找,但不支持 b,c或c進(jìn)行查找
最左原則是指:mysql會一直向右匹配直到遇到范圍查詢(>、<、between、like)就停止匹配,索引可以任意順序,mysql的查詢優(yōu)化器會幫你優(yōu)化成索引可以識別的形式,所以這兩條都是會命中索引的。要記住和順序是無關(guān)的。
使用i查詢時,in查詢條件超過數(shù)據(jù)庫表的一半
where條件中使用NOT IN
where 語句中使用 is null 或者 is not null,當(dāng)查詢量達(dá)到總表的30%以上時
如果排序使用了索引,而select列未使用索引列,則該索引失效
這是因為優(yōu)化器執(zhí)行直接執(zhí)行全表掃描速度更快。主鍵索引除外,任何一張表都有一個唯一索引primary,索引列為主鍵列。
對創(chuàng)建索引的一些技巧總結(jié)
首先數(shù)據(jù)量小的表不需要建立索引
因為數(shù)據(jù)量小的表即使建立索引也不會有大的用處,還會增加額外的索引開銷 。
不經(jīng)常引用的列不要建立索引,因為不常用,即使建立了索引也沒有多大意義
**經(jīng)常頻繁更新的列不要建立索引,因為肯定會影響插入或更新的效率 **
盡量避免在 where 子句中使用 != 或者 <> 操作符,查詢引用會放棄索引而進(jìn)行全表掃描
數(shù)據(jù)類型越小越簡單的索引更好
越小越簡單的數(shù)據(jù)類型通常在磁盤、內(nèi)存和cpu緩存中需要的空間更少,處理起來更快。
字段內(nèi)容盡量避免NULL
在組合索引中某一索引列有null值,則索引失效。這句話其實是不對的,在單列索引中索引列有null值不會失效。在組合索引中索引列有null值也是可以使用組合索引的,MySQL難以優(yōu)化引用了可空列的查詢,它會使索引、索引統(tǒng)計和值更加復(fù)雜??煽樟行枰嗟膬Υ婵臻g,還需要在MySQL內(nèi)部進(jìn)行特殊處理。當(dāng)可空列被索引的時候,每條記錄都需要一個額外的字節(jié),還可能導(dǎo)致 MyISAM 中固定大小的索引(例如一個整數(shù)列上的索引)變成可變大小的索引,所以盡量避免null值。
SQL中,含有空值的列很難進(jìn)行查詢優(yōu)化,因為它們使得索引、索引的統(tǒng)計信息以及比較運算更加復(fù)雜??梢圆捎?、一個特殊的值或者一個空串代替空值 。
有大量重復(fù)的列不要創(chuàng)建索引。
mysql查詢結(jié)果要小于30%才會使用索引,不然會使用全表掃描。mysql優(yōu)化器認(rèn)為全表掃描的成本小于索引,所以放棄索引,這是很多情況下沒使用索引的原因。具有唯一性或者重復(fù)性很少的列建立索引會非常有效。
減少索引長度
設(shè)置索引時可能的話應(yīng)該指定一個前綴長度。例如,如果有一個CHAR(255)的 列,如果在前10 個或20 個字符內(nèi),多數(shù)值是惟一的,那么就不要對整個列進(jìn)行索引。短索引不僅可以提高查詢速度而且可以節(jié)省磁盤空間和I/O操作。
在實際應(yīng)用的過程中,mysql并不總會選擇合理的索引進(jìn)行查詢,此時便可以使用force index(index name)來強(qiáng)制告訴mysql選擇哪一個索引。使用一下sql查詢:
select * from t_test3 force INDEX (t_test_name) where name in ('a','b');其對應(yīng)的執(zhí)行計劃與上圖的執(zhí)行計劃相同,采用的是sql中指定的索引。
因此我們在一些情況下首先可以適當(dāng)?shù)氖褂胒orce index(indexname) 強(qiáng)制告訴mysql使用什么索引。force index( index name )指令可以指定本次查詢使用哪個索引!一條sql只會用到一個索引,mysql優(yōu)化器會計算出一個合適的索引,但是這個索引不一定是最好的。force index()指令可以避免MySql優(yōu)化器用到了一個低效的索引,并可以提高sql的執(zhí)行效率。
終極優(yōu)化思路:干掉join,優(yōu)化業(yè)務(wù)邏輯
參考:mysql的索引及索引誤區(qū)詳解
總結(jié)
以上是生活随笔為你收集整理的深入浅出MYSQL查询索引失效的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python括号匹配问题_支持通配符的括
- 下一篇: linux cmake编译源码,linu