sql中索引不會被用到的幾種情況


1、查詢謂詞沒有使用索引的主要邊界,換句話說就是select *,可能會導致不走索引。
比如,你查詢的是SELECT * FROM T WHERE Y=XXX;假如你的T表上有一個包含Y值的組合索引,但是優化器會認為需要一行行的掃描會更有效,這個時候,優化器可能會選擇TABLE ACCESS FULL,但是如果換成了SELECT Y FROM T WHERE Y = XXX,優化器會直接去索引中找到Y的值,因為從B樹中就可以找到相應的值。
 
2、單鍵值的b樹索引列上存在null值,導致COUNT(*)不能走索引。
如果在B樹索引中有一個空值,那么查詢諸如SELECT COUNT(*) FROM T 的時候,因為HASHSET中不能存儲空值的,所以優化器不會走索引,有兩種方式可以讓索引有效,一種是SELECT COUNT(*) FROM T WHERE XXX IS NOT NULL或者把這個列的屬性改為not null (不能為空)。
 
3、索引列上有函數運算,導致不走索引
如果在T表上有一個索引Y,但是你的查詢語句是這樣子SELECT * FROM T WHERE FUN(Y) = XXX。這個時候索引也不會被用到,因為你要查詢的列中所有的行都需要被計算一遍,因此,如果要讓這種sql語句的效率提高的話,在這個表上建立一個基於函數的索引,比如CREATE INDEX IDX FUNT ON T(FUN(Y));這種方式,等於Oracle會建立一個存儲所有函數計算結果的值,再進行查詢的時候就不需要進行計算了,因為很多函數存在不同返回值,因此必須標明這個函數是有固定返回值的。
 
4、隱式轉換導致不走索引。
索引不適用於隱式轉換的情況,比如你的SELECT * FROM T WHERE Y = 5 在Y上面有一個索引,但是Y列是VARCHAR2的,那么Oracle會將上面的5進行一個隱式的轉換,SELECT * FROM T WHERE TO_NUMBER(Y) = 5,這個時候也是有可能用不到索引的。
 
5、表的數據庫小或者需要選擇大部分數據,不走索引
在Oracle的初始化參數中,有一個參數是一次讀取的數據塊的數目,比如你的表只有幾個數據塊大小,而且可以被Oracle一次性抓取,那么就沒有使用索引的必要了,因為抓取索引還需要去根據rowid從數據塊中獲取相應的元素值,因此在表特別小的情況下,索引沒有用到是情理當中的事情。
6、cbo優化器下統計信息不准確,導致不走索引
很長時間沒有做表分析,或者重新收集表狀態信息了,在數據字典中,表的統計信息是不准確的,這個情況下,可能會使用錯誤的索引,這個效率可能也是比較低的。
7、!=或者<>(不等於),可能導致不走索引,也可能走 INDEX FAST FULL SCAN
例如select id  from test where id<>100
8、表字段的屬性導致不走索引,字符型的索引列會導致優化器認為需要掃描索引大部分數據且聚簇因子很大,最終導致棄用索引掃描而改用全表掃描方式,
由於字符型和數值型的在insert的時候排序不同,字符類型導致了聚簇因子很大,原因是插入順序與排序順序不同。詳細點說,就是按照數字類型插入(1..3200000),按字符類型('1'...'32000000')t排序,在對字符類型使用大於運算符時,會導致優化器認為需要掃描索引大部分數據且聚簇因子很大,最終導致棄用索引掃描而改用全表掃描方式。
下面展示測試結果,
兩個表的數據類型相似(只是ID字段類型不同),各插入了320萬數據,ID字段范圍為1~3200000。
 
模擬場景
相關代碼如下:
 
對於普通的采用數值類型的字段,范圍查詢就是正常的索引范圍掃描,執行效率很高。
 
對於文本類型字段的表,范圍查詢就是對應的全表掃描,效率較低是顯而易見的。
解決方法
 
將SQL語句由開放區間掃描(>=),修改為封閉區間(between xxx and max_value)。使得數據在索引局部順序是“對的”。如果采用這種方式仍然不走索引掃描,還可以進一步細化分段或者采用“逐條提取+批綁定”的方法。
 
9.建立組合索引,但查詢謂詞並未使用組合索引的第一列,此處有一個INDEX SKIP SCAN概念,
10、like '%liu' 百分號在前
11,not in ,not exist
可以嘗試把not in 或者 not exsts改成左連接的方式(前提是有子查詢,並且子查詢有where條件)。
 
 
轉摘:http://blog.csdn.net/yezhouyong/article/details/73275076


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM