大部分的性能問題其實都是索引應用的問題,Where子句、Order By、Group?By 都要用到索引。
一般開發人員認為將索引建全了就可以下班回家了,實則還有頗多的思量和陷阱。
索引列上不要使用IS NULL 或 IS NOT NULL
×?SELECT?Col?FROM?tbl?WHERE?col?IS?NULL
索引列上不要使用函數
×?SELECT?Col?FROM?tbl?WHERE?substr(name
,
?
1
,
?
3
)?
=
?'ABC'
○?SELECT?Col?FROM?tbl?WHERE?name?LIKE?'ABC%'
WHERE子句中,如果索引列是函數的一部分.優化器將不使用索引而使用全表掃描.○?SELECT?Col?FROM?tbl?WHERE?name?LIKE?'ABC%'
索引列上不要使用NOT ( != 、 <> )
×?SELECT?Col?FROM?tbl?WHERE?col?!
=
?
10
○?SELECT?Col?FROM?tbl?WHERE?col?>? 10 ?OR?col?<? 10
○?SELECT?Col?FROM?tbl?WHERE?col?>? 10 ?OR?col?<? 10
記住
,
索引只能告訴你什么存在于表中
,
而不能告訴你什么不存在于表中
.
要避免在索引列上使用NOT, NOT會產生在和在索引列上使用函數相同的影響. 當ORACLE”遇到”NOT,他就會停止使用索引轉而執行全表掃描。
索引列上不要進行計算
×?SELECT?Col?FROM?tbl?WHERE?col?/?
10
?>?
10
○?SELECT?Col?FROM?tbl?WHERE?col?>? 10 ?*? 10
這是最最普遍的失效陷阱,比如where trunc(order_date)=trunc(sysdate), i+2>4。索引失效的原因也簡單,索引是針對原值建的二叉樹,你將列值*3/4+2折騰一番后,原來的二叉樹當然就用不上了。○?SELECT?Col?FROM?tbl?WHERE?col?>? 10 ?*? 10
?