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