昨天碰到一個很有意思的問題,一個sql 語句,加上 SoftUseLine like '%OQC%' 之后,速度就特別慢。去掉該條件之后,速度就快起來了。
查看sql 語句的執行情況,發現加上那個查詢條件之后,SoftWareDetailInfo表的邏輯讀取變成了1300374 次,
可是這個查詢字段明明已經加上Index_SoftWareDetail索引了,怎么會邏輯讀取還這么大呢。查看sql profile 的詳細信息,發現sql 語句,沒有走那個索引。
於是,加上WITH(INDEX(Index_SoftWareDetail)) ,讓sql 必須走這個索引試試。Sql查詢立馬變快了。sql profile 顯示,已經走了Index_SoftWareDetail索引。看來是索引創建的有問題,導致查詢計划,沒有走該索引,而是進行全表掃描。所以導致查詢速度變慢。
於是把所有索引重新調整下。Ok了。
數據庫中索引什么時候會失效呢?
總結下數據庫中索引失效的問題,不過有些沒有經過測試。這里僅供自己參考。
首先,所謂失效。並不真的就是這個索引被刪除了。而是在某些情況下,DBMS不會檢索索引列表了。執行速度和沒有這個索引時的速度一樣。但是再執行另外的一條語句。同樣的索引又正常起作用。所以索引的失效是針對某條sql語句,某個查詢條件的,而不是針對索引本身的。
哪類語句執行時索引不起作用呢。總結如下:
1. 索引字段進行判空查詢時。也就是對索引字段判斷是否為NULL時。語句為is null 或is not null。
比如:select * from SoftWareDetailInfo where CreateTime is null 此時就不檢索time字段上的索引表了。也就是索引在這條語句執行時失效了。
接着再執行
select * from SoftWareDetailInfo where CreateTime = '2015-04-11 00:00:00' 此時就會檢索索引表了。索引又起作用了。
2. 對索引字段進行like查詢時。比如:select * from SoftWareDetailInfo where SoftUseLine like '%OQC%'。不過網上有的例子說like 'xx%'索引起作用。我沒試過。
3. 判斷索引列是否不等於某個值時。‘!=’操作符。比如:select * from SoftWareDetailInfo where SoftUseLine != 0
4. 對索引列進行運算。這里運算包括+-*/等運算。也包括使用函數。比如:
select * from SoftWareDetailInfo where SoftUseLine +0= 0
此時索引不起作用。
select * from SoftWareDetailInfo where count(SoftUseLine) = 0
此時索引也不起作用。
也就是說如果不是直接判斷索引字段列,而是判斷運算或其它函數處理后的索引列索引均不起作用。
5. 復合索引中的前導列沒有被作為查詢條件。比如:Index_SoftWareDetail索引包含(a,b,c) 三列,但是查詢條件里面,沒有a,b 列,只有c 列,那么 Index_SoftWareDetail索引也不起作用。