oracleインデックスの制限を回避
インデックスの制限は、経験のない開発者がよく犯すエラーの一つです.SQLには多くのトラップがあり、インデックスが使用できません.一般的な問題について説明します.
4.1等しくないオペレータの使用(<>、!=)次のクエリは、cust_rating列にインデックスがある場合でも、クエリ文は全テーブルスキャンを実行します.select cust_Id,cust_name from customers where cust_rating<>'aa';上記の文を次のクエリ文に変更することで、ルールベースのコストベースのオプティマイザではなくオプティマイザ(よりスマート)では、インデックスが使用されます.select cust_Id、cust_name from customers where cust_rating<'aa'or cust_rating>'aa';オペレータに等しくないことをOR条件に変更することで、インデックスを使用してテーブル全体のスキャンを回避できます.4.2 IS NULLまたはIS NOT NULLを使用してISを使用しますNULLまたはIS NOT NULLは、インデックスの使用を制限します.NULL値は定義されていないためです.SQL文でNULLを使うのは面倒です.そこで,開発者はテーブルを作成する際にインデックスが必要な列をNOT NULLにすることを提案する.インデックスされたカラムにNULL値がある場合、このインデックスは使用されません(インデックスがビットマップインデックスでない限り、ビットマップインデックスについては後で詳しく説明します).4.3関数を使用して関数ベースのインデックスを使用しない場合、SQL文のWHERE句でインデックスが存在する列に関数を使用する場合、オプティマイザはこれらのインデックスを無視します.次のクエリではインデックスは使用されません.(関数ベースのインデックスでない限り)
4.1等しくないオペレータの使用(<>、!=)次のクエリは、cust_rating列にインデックスがある場合でも、クエリ文は全テーブルスキャンを実行します.select cust_Id,cust_name from customers where cust_rating<>'aa';上記の文を次のクエリ文に変更することで、ルールベースのコストベースのオプティマイザではなくオプティマイザ(よりスマート)では、インデックスが使用されます.select cust_Id、cust_name from customers where cust_rating<'aa'or cust_rating>'aa';オペレータに等しくないことをOR条件に変更することで、インデックスを使用してテーブル全体のスキャンを回避できます.4.2 IS NULLまたはIS NOT NULLを使用してISを使用しますNULLまたはIS NOT NULLは、インデックスの使用を制限します.NULL値は定義されていないためです.SQL文でNULLを使うのは面倒です.そこで,開発者はテーブルを作成する際にインデックスが必要な列をNOT NULLにすることを提案する.インデックスされたカラムにNULL値がある場合、このインデックスは使用されません(インデックスがビットマップインデックスでない限り、ビットマップインデックスについては後で詳しく説明します).4.3関数を使用して関数ベースのインデックスを使用しない場合、SQL文のWHERE句でインデックスが存在する列に関数を使用する場合、オプティマイザはこれらのインデックスを無視します.次のクエリではインデックスは使用されません.(関数ベースのインデックスでない限り)
select empno,ename,deptno
from emp
where trunc(hiredate)='01-MAY-81';
, 。
select empno,ename,deptno
from emp
where hiredate<(to_date('01-MAY-81')+0.9999);
4.4
。
,account_number VARCHAR2 ,
account_number 。 。
select bank_name,address,city,state,zip
from banks
where account_number = 990354;
Oracle where to_number(account_number)=990354,
, :
select bank_name,address,city,state,zip
from banks
where account_number ='990354';
: Oracle ,
Explain Plan “ ”。