2016-06-29 5 views
0

集計関数でSQLクエリを使用しているときにパフォーマンス上の問題が発生するため、インデックス作成の仕組みを理解することをお勧めします。私は理解できませんでした一つのことに出くわした:Oracleインデックスの作成構文

SELECT SUM(field1) FROM table1 WHERE timeofrequest BETWEEN 1 AND 2; 

:これら二つの作成ディレクティブの違いは何ですか?:

1.)CREATE INDEX FIELD1_INDEX ON TABLE1 (FIELD1) ONLINE TABLESPACE XXX; 
    CREATE INDEX timeofrequest_INDEX ON TABLE1 (timeofrequest) ONLINE TABLESPACE XXX; 

2.)CREATE INDEX COMBINED_INDEX ON TABLE1 (FIELD1, FIELD2) ONLINE TABLESPACE XXX; 

私が求めている理由は、私のようなクエリを持っているということです表1には多くのデータが含まれているため、このクエリーには20秒以上かかります。長いランタイムを避けるために、私はアプローチ1に進み、影響を受ける各フィールドのインデックスを作成しようとしました。確かに、それはまだ遅すぎる。実行計画を分析すると、timeofrequestインデックスが使用されていますが、field1のインデックスは使用されていません。 1つのステートメントで結合されたものを作成すると役立つでしょうか?何か違いはありますか?

答えて

0

したがって、最初の2つのインデックスは、最初の2つがインデックスのSINGLE列のみを使用する点で、3番目のインデックスとは異なります。 3番目の索引は索引に2つの異なる列で構成されますが、索引にリストされている最初の列のみを指定した場合でも3番目の索引を使用できます。これは複合索引と呼ばれます。 Oracleは実際には単一の問合せ文でSINGLE索引のみを使用でき、CBOは使用する最良のオプションを見つけ出します。

最初の例では、個々の列に対して2つのインデックスがあります。 2番目の例は、2つの列を持つ単一索引です。あなたの最初の例では、どちらか一方のみを使用しますが、特定の単一select文に対しては両方を使用しません(CBOはクエリに基づいて何を使用するかを決定します)。

例:

SELECT SUM(field1) FROM table1 WHERE timeofrequest BETWEEN 1 AND 2; 

これだけあなたがtimeofrequestに対して置かれているインデックスを使用しようとします。実際にはレンジスキャンを試みます。 2番目のインデックスのための

例:

SELECT SUM(field1) FROM table1 WHERE FIELD1 = 'x'; 

は、あなただけの「FIELD1」に対するINDEXを持っていなかったと仮定すると、これはあなたの場所に持ってCOMBINED_INDEXを利用し、あなたのインデックスの最初のフィールドごとにすべてのレコードをフェッチします。

あなたが持っていた場合:インデックスはまず、FIELD2をFIELD1を使用して周りに構築されているよう

SELECT SUM(field1) FROM table1 WHERE FIELD2 = 'y'; 

これは、combined_indexを使用することはありません。

あなたが持っていた場合:

SELECT SUM(field1) FROM table1 WHERE FIELD1 = 'x' and FIELD2 = 'y'; 

これはまだCOMBINED_INDEXを利用することになるが、ここであなたは粒度の細かいレベルを提供します。これは、完全なインデックス(field1とfield2 ...)を使って、あなたの行をずっと早く返すでしょう。なぜこれは役に立ちますか?まあ、FIELD1のインデックスを持つことができ、単にfield1だけを検索するだけでも数千(または何万、何百万)のレコードが得られるので、別の列をインデックスの一部として提供できる必要なレコードをターゲットにするだけで、より高い選択性が得られます。

重要なメモ! CBOは最良のアプローチを思い出すことを思い出してください。カーディナリティが悪い場合(リサーチテーブルカーディナリティ...)を使用すると、インデックスをまったく使用しない可能性もあり、CBOによれば完全なテーブルスキャンが優れている可能性があります。カーディナリティが高く、まだ索引を使用していない場合は、表とその索引を分析してから、新しい結果が得られるかどうかを確認するためにEXPLAIN PLANを再実行する必要がある可能性があります。また、テーブル内のデータの多くが変更され、最近分析されていないために、カーディナリティが低い可能性があります。あなたのテーブル/インデックスを分析することは非常に重要なことであり、簡単に見過ごすことができます。複数の機会に私はテーブルやインデックスの再分析を行うだけで、すばらしい改善が見られたという事実を発見しました。

分析テーブルとDBMS_STATSの使用を確認してください。あなたが大量のデータを持っており、あなたの「時間要求の」列は実際には多分5000万レコードのテーブル内の値(の小さな明確なセットを持っている場合

https://docs.oracle.com/cd/B28359_01/appdev.111/b28419/d_stats.htm

別の解決策は、あまりにだけありますされていること20個の異なる値..)、分割されたテーブルを設定し、そこからインデックスを提供することを選ぶかもしれません。クエリの実行時間が大幅に短縮されます。

+0

ありがとう、私はあなたの助けに感謝します –