2011-10-19 12 views
4

私はデータ変換を行っています。新しいデータベーステーブルには12個程度の列があり、古いデータベースの各製品の最新のトランザクションのみを検索する必要があります。私の質問では12回、大規模な取引テーブルから単一の価値が必要です。さらに効率的なSQLクエリ

最新のトランザクションを取得するには、ネストされた内部結合を使用して '最大'を検索しています。これらのネストされたquerysが効率を殺しているとサブテーブルは巨大です。私のクエリは、わずか100サンプルのサンプルを引っ張ると約20秒かかります。私は〜10,000を持っています。ネストされたクエリをより効率的にするための提案はありますか?これらのネストされた内部結合の1つの例を次に示します。

LEFT JOIN coverage_schedule CS_PL 
    ON R.risk_pk = CS_PL.risk_fk 
     AND CS_PL.coverage_type = 'HOMCVGE' 
    LEFT JOIN (Coverage_tran CT_PL 
       JOIN (SELECT DISTINCT MAX(pct.coverage_tran_pk) AS recent, 
            pct.coverage_schedule_fk, 
            pcs.coverage_type 
        FROM Coverage_tran pct 
          LEFT JOIN TRANSACTION pt 
           ON pct.transaction_fk = pt.transaction_pk 
          LEFT JOIN coverage_schedule pcs 
           ON pct.coverage_schedule_fk = 
           pcs.po_coverage_schedule_pk 
           AND pcs.coverage_type = 'HOMCVGE' 
        WHERE pt.transaction_cycle = 'issued' 
          AND pct.cvg_status = 'Active' 
        GROUP BY pct.coverage_schedule_fk, 
           pcs.coverage_type, 
           pt.transaction_cycle) mCT2 
       ON CT_PL.coverage_schedule_fk = mCT2.coverage_schedule_fk 
        AND CT_PL.coverage_tran_pk = mCT2.recent) 
    ON CS_PL.coverage_schedule_pk = CT_PL.coverage_schedule_fk 
     AND CT_PL.cvg_status = 'Active' 

私はまた、「アクティブ」状態で製品だけに制限しましたカバレッジが「HOMCVGE」と呼ばれるこのサンプルでは正しい「カバレッジ・タイプ」のちょうど取引にネストされたテーブルのクエリを制限しようとしました。私はテーブルから 'カバレッジ'カラムを削除しようとしました。なぜなら、カラムとしても、ジョインの制限/ルールとしても必要ないからです。私は、サンプルサイズを制限するとより効率的になると思っていたが、目立った効果は見られなかった。制限を追加してテーブルのサイズを縮小するだけですか?制限を 'join'または 'where'節に置く方が良いでしょうか?

実行計画では、上記のネストされたクエリのコストが11.6911/8%であることが示されています。これはクエリ全体の中で最も高価なものです...しかし、それはそれを遅くすると私にはすでに分かっています。

私が使用できるヒント、手がかり、またはツールはありますか?私はSQL上でクラスを取らなかったので、私はベストプラクティスを教えられておらず、Big Oのコストも知らないと認めます。私はちょうど10分前に実行計画を見つけました。

更新------------------- 不要な列やグループを削除することで数秒間を削ることができました。ありがとう。私はそれをより効率的にすることができればと思います。可能であれば、 'where'句ではクエリに制限を加え、 'JOIN'句に直接は付加しない方がよいことも発見しました。

X-Zero、私はそれを見る方法は2つあります。基本的に私は製品の現在の機能を探しています。新しいデータベースでは、現在のフィーチャを個別の列としてインポートしています。古いデータベースでは、フィーチャは、フィーチャへの変更の追加、削除、または引用だけに関連する、製品上のすべてのトランザクションを含む巨大なトランザクションテーブルに格納されます。製品の各機能には、独自のトランザクションセットがテーブルに設定されています。製品にこの機能がなかった場合は、レコードはまったくありません。簡略化されたトランザクションテーブルを作るためにあなたが言うように行います

  1. とCTEを使用します。私もちょうど12は、だから私はどちらかのことができ、テーブル内のすべての機能タイプを引っ張っていないよ(したがって、左の使用が加入します)関連するフィーチャセットのみの最新のアクティブなトランザクションのみを格納し、メインクエリでこのテーブルから製品を引き出します。

  2. ここでは、各機能にメインクエリ内の最新のトランザクションの独自のサブクエリ/テーブルがあるようにしています。これらの表にはそれぞれ1つのフィーチャーしか含まれていません。私はこれらのサブクエリを同一にしようとしましたが、私はまったく使用していないテーブルの多くのフィーチャタイプのために、それらをユニークにする方が効率的でした。

どちらの方が良いか分かりません。 CTEが(私が望む12個の機能に限定している限り)CTEが進む方法かもしれないように思えますが、それは自分自身を教えるもう一つのことです。

ありがとうございました。

+1

私の意見では、総コストの8%が11.6911であれば、さらに問題があるかもしれません。 –

+1

懸念している部分だけでなく、クエリ全体を投稿できますか?あなたはおそらく、返される列の束を除外することができますが、少なくとも完全なSELECT FROM ... WHERE ...など – DRapp

+0

あなたがA)全体のクエリをB)テーブル定義とC)実行計画。 –

答えて

5

サブクエリのDISTINCTキーワードを削除します。 MAXはGROUPing列ごとに1つの値しか返さないため、DISTINCTは冗長です。

EDIT:下記のMartinのコメントは正しいですが、サブクエリでエラーが発生する可能性があります。 3つの列すべてでグループ化するか、最初の2つだけでグループ化する必要がありますか?前者の場合、私は私の答えを撤回します。後者の場合は、サンプルをクリーンアップする必要があります。

+0

私はDistinctを削除し、私はサブクエリの列数を単純化することを検討しています。また、変数を作成しようとする可能性もあります。大規模な静的テーブルを作成するために変数を使用したことはありません。より効率的ではないなら、可能でなければなりません。クエリについては、その157行の長いと書いて私を1日半かかりました。私は、すべてのことを投稿し、それをすべて説明することで、みんなを拷問するつもりはありません。私はさまざまな種類の列の例を簡略化したバージョンを投稿するかもしれません。 – Poko

+0

@Stuart私が作ったコメントを参照して編集に気づいただけです。とにかく 'pt.transaction_cycle'グループが1つだけ確保されていることに気づいたので、' DISTINCT'が 'GROUP BY'とは異なるカラムに適用されているというコメントを削除しました。私は、SQL Serverは 'DISTINCT 'も余分であることを認識するだろうと思う。 –

1

サブクエリをローカル変数に移動し、サブクエリを使用するクエリに先立ってそれらを独立したクエリにすることがパフォーマンスを向上させる方法です1回だけ。もちろん、これは特定の固定クエリでのみ可能です。また、複数のクエリが1つのアトミック単位として実行されるかどうかという懸念もあります。

また、オプティマイザが正常に動作しない場合はとしてください。

+0

テーブルの可否は、結果セットが小さい場合にのみ効率的です。結果セットが大規模な一時テーブルまたはCTEの場合 – HLGEM

関連する問題