在索引列上使用函式使得索引失效的是常見的索引失效原因之一,因此盡可能的避免在索引列上使用函式。儘管可以使用基於函式的索引來
解決索引失效的問題,但如此一來帶來的比如磁碟空間的占用以及列上過多的索引導致dml效能的下降。本文描述的是乙個索引列上使用函式使
其失效的案例。
一、資料版本與原始語句及相關資訊
1.版本資訊
2.原始語句與其執行計畫
從執行計畫可以看出,sql語句使用了全表掃瞄,而where 子句中只有唯一的一列business_date
3.表上的索引資訊
從索引的情況上來看有乙個基於主鍵的索引包含了business_date列,而查詢語句並沒有走索引而是選擇的全表掃瞄,而且預估所返回
的行rows與bytes也是大的驚人,cost的值96399,接近10w。
二、分析與改造sql語句
1.原始的sql語句分析
sql語句中where子句的business_date列實現對記錄過濾
business_date <= '20110728'條件不會限制索引的使用
substr(business_date, 1, 6) = substr('20110728', 1, 6)使用了substr函式,限制了優化器選擇索引
基於business_date列來建立索引函式,從已存在的索引來看,必要性不大
2.改造sql語句
substr(business_date, 1, 6) = substr('20110728', 1, 6)的實質是等於當月,即限制返回的行為從2011.7.1日至2011.7.28
因此其返回的記錄大於等於2011.7.1,且小於2011.7.28
做如下改造
business_date >=to_char(last_day(add_months(to_date('20110728','yyyymmdd'),-1)) + 1,'yyyymmdd')
3.改造後的sql語句
4.改造後的執行計畫
改造後可以看到sql語句的執行計畫已經由原來的全表掃瞄改為執行index skip scan,但其cost也並沒有降低多少
三、進一步分析
1.表的相關資訊
2.索引的相關資訊
3.嘗試在business_date列上建立索引
建立索引後聚簇因子較小,差不多接近表上塊的數量
4.使用新建立索引後的執行計畫
從上面的執行計畫看出,sql語句已經選擇了新建的索引
儘管返回的rows,bytes沒有明顯的變化,但cost已經少了近7倍。
mysql索引失效 常見mysql索引失效條件
使用索引的一般語句 1 where條件中有or,除非or的所有欄位都有索引,只要有乙個沒有索引,就不走索引 explain select from jf user ju where ju.user id or ju.superior1 yyy user id是主鍵,superior1是普通索引,結果...
mysql in 索引 失效 in 索引失效的問題
簡單的in查詢 索引失效 步驟1 檢查建立索引沒有 order status 欄位為普通索引的tinyint型別 2 檢查是否使用了使索引失效的語句 3 explain檢視執行計畫 而 in 1 時會走索引 5 檢視是否關閉的全域性的索引 comment顯示disabled則表示關閉了索引 show...
mysql 主鍵失效 MySQL索引(索引失效)
索引 索引也是一張表,該錶儲存了主鍵與索引字段,並指向實體表的記錄。myisam儲存引擎,資料檔案 索引檔案 表結構檔案分開儲存 innodb儲存引擎,資料和索引儲存在乙個檔案中 b tree索引 hash索引 hash索引 只有memory儲存引擎支援 查詢一條記錄的速度非常快 b tree索引 ...