私はインタビューでこの質問に遭遇しましたが、答え方がわかりませんでした。
列にインデックスを持つテーブルがあり、次のクエリを実行します。
select * from table_name where column_having_index="some value";
クエリに時間がかかりすぎて、インデックスが使用されていないことがわかりました。インデックスを使用するとクエリのパフォーマンスが向上すると思われる場合、クエリにインデックスを使用させるにはどうすればよいでしょうか?
オプティマイザーのヒントを使用できます
select /*+ INDEX(table_name index_name) */ from table
等...
オプティマイザ ヒントの使用の詳細: http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/hintsref.htm
インデックスが使用されない理由は多数考えられます。ヒントを指定した後でも、Oracle オプティマイザーが別の方法で判断し、 Index を使用しないと決定する可能性があります。EXPLAIN PLAN 部分を調べて、INDEX を使用するステートメントと INDEX を使用しないステートメントのコストを確認する必要があります。
Oracle が CBO を使用すると仮定します。ほとんどの場合、オプティマイザーが INDEX のコストが高いと判断した場合、ヒントで指定しても、オプティマイザーは無視してフル テーブル スキャンを続行します。最初のアクションは、DBA_INDEXES をチェックして、統計が LAST_ANALYZED であることを確認することです。分析されていない場合は、分析用のテーブル、インデックスを設定できます。
begin
DBMS_STATS.GATHER_INDEX_STATS ( OWNNAME=>user
, INDNAME=>IndexName);
end;
テーブル用。
begin
DBMS_STATS.GATHER_TABLE_STATS ( OWNNAME=>user
, TABNAME=>TableName);
end;
極端な場合は、自分で統計を設定してみることができます。
インデックスを使用するとクエリのパフォーマンスが向上すると思われる場合、クエリにインデックスを使用させるにはどうすればよいでしょうか?
最初に、完全なデータセットを返すためにインデックスがより良い結果をもたらすことをもちろん検証しますよね?
ここではインデックス ヒントが重要ですが、それを指定する最新の方法は、インデックスの命名方法ではなく、列の命名方法を使用することです。あなたの場合、次を使用します:
select /*+ index(table_name (column_having_index)) */ *
from table_name
where column_having_index="some value";
より複雑なケースでは...
select /*+ index(t (t.column_having_index)) */ *
from my_owner.table_name t,
...
where t.column_having_index="some value";
複合インデックスに関しては、すべての列を指定する必要があるかどうかはわかりませんが、良い考えのようです。ここのドキュメントを参照してくださいhttp://docs.oracle.com/cd/E11882_01/server.112/e26088/sql_elements006.htm#autoId18複数の index_specs と複数のインデックスに対する index_combine の使用についてhttp://docs.oracle. index_specでの複数列の指定については、com/cd/E11882_01/server.112/e26088/sql_elements006.htm#BABGFHCHを参照してください。
column_having_index には適切なインデックスがあり、それを使用すると実際にパフォーマンスが向上しますが、Oracle はそれを使用しませんでした...テーブルの
統計を収集して、インデックス アクセスが役立つことをオプティマイザーに認識させる必要があります。直接ヒントを使用することはお勧めできません。