2016-10-25 5 views
0

私はここ数週間、幾分単純なクエリのパフォーマンスを向上させています。私は最初に質問を書いて、次に現在使われているものと私の考えを記述することにします。幾分単純なクエリのパフォーマンスの問題

表:約100万行
統計集まっ週刊

例:

SELECT c1,c2,c3,c4,TO_NUMBER(c5) 
FROM TABLE 
WHERE CODE = 3 AND 
     NUMBER IN (115,433,54542,435930,22565,3293029,3222) AND 
     DATE BETWEEN TO_DATE('01-01-2010','DD-MM-YYYY') AND TO_DATE('01-01-2015','DD-MM-YYYY') AND 
     AMOUNT > 1000 

現在使用されているCODE、NUMBER、およびDATEのカラムにインデックスがあるが、クエリ完了までに数分かかる。テストされたNUMBER列のインデックスもありますが、パフォーマンスはやや向上しますが、クエリはまだ遅すぎます。
また、テーブルは月ごとにDATEで分割されます。

既存のインデックスが機能していないため、今では独自のテーブルを作成して、私が支配しています。

私の考えは次のとおりです。
1)CODEでパーティションまたはマテリアライズド・ビューを作成します。テーブルの半分はcode = 3なので、私の考えは、これが事実上テーブルの大きさの半分になるということです。
2)DATEは実際には時間とともに保存されます。この方法ですべての日付を切り捨ててパーティションを作成すると、パフォーマンスが向上する可能性があります。
3)4つの列すべてにインデックスを作成して、パフォーマンスが向上するかどうかを確認します。

これはすべて私が実際に持っているものです。他の提案は非常に高く評価されています!

+0

DATEの範囲によるパーティション分割。 – Alfabravo

+1

説明計画の出力を表示してください。 – OldProgrammer

答えて

0

あなたの質問は、実際のインデックスには曖昧です。

このクエリの場合、最適なインデックスは(code, number, date, amount)です。

ただし、100,000,000行のテーブルから5年間分のデータをフェッチしています。私は他の列がどのように選択的であるか分かりませんが、それは潜在的に多くのデータが返されることです。それはパフォーマンスの問題を説明するかもしれません。

+1

@onedaywhen。 。 。 'code'は等価条件を持つため、最初に指定する必要があります。 –

1

テーブルは、DATE列(おそらくレンジパーティションを意味します)に基づいてパーティション化されているとします。

インデックスはありますが、それらがグローバル(1つのインデックスはすべてのパーティションをカバーします)またはローカル(各パーティションのインデックスは1つ)であるかどうかは指定しません。

私がアドバイスを思いつくために試みることは、Oracleがどのようにクエリを実行しているかを推測することです。それはそれが使用することができる可能性のある様々な計画があるように思えます。

私の主なアドバイスは、実行計画を見て理解する方法を学ぶことです。あなたはそれがより良くなるかもしれないことの本当の考えを得るために、それが何をしているのかを理解する必要があります。

しかし、私は適用されるかもしれないし、そうでないかもしれないいくつかの提案をします。あなたのインデックスを仮定し

はグローバルで、その後、私はまたはがインデックスを使用して検索を行います(その場合、それは、フルスキャン関連のパーティションをある)DATEに基づいてパーティションの除去を行うオプティマイザはするオプションを持っていると思うのいずれか。パーティションを削除して各パーティション内でインデックスルックアップを使用することができるため、ローカルインデックスを使用することで改善が得られる可能性があります(この場合、少なくともこのクエリではインデックス内のDATEは無意味です)。

おそらく、AMOUNTをインデックスに追加すると役立ちますが、これはAMOUNT > 1000が相当数の行を削除するかどうかによって異なります。

すべてのフィルタ列と選択したすべての列をカバーするインデックスを作成する可能性があります。この場合、テーブルをまったく見ずにインデックスを検索することでクエリを満たすことができます。