2017-04-24 12 views
0

以下のクエリは、レコード数が膨大なテーブルに対して実行されます.22029464までです。これは実行に約20〜25分ほどかかるものです。これを別の方法で最適化または書き直す範囲はありますか?必要なインデックスがクエリプランが全く欠落インデックスの要件を示していない、すべてのテーブルの上に存在するSQL Serverクエリの最適化 - 2千万レコードのテーブル内のMultiJoins

SELECT stg.* 
    FROM dbo.s_NIIT_ResultValues stg 
    WHERE stg.resultId IN (SELECT resultId 
           FROM  Data_NIIT.dbo.NIIT_Results) 
      AND (stg.resultIntValueId IS NULL 
        OR stg.resultIntValueId IN (
        SELECT resultIntValueId 
        FROM  Data_NIIT.dbo.NIIT_ResultIntValues) 
       ) 
      AND (stg.resultBoolValueId IS NULL 
        OR stg.resultBoolValueId IN (
        SELECT resultBoolValueId 
        FROM  Data_NIIT.dbo.NIIT_ResultBoolValues) 
       ) 
      AND (stg.resultStringValueId IS NULL 
        OR stg.resultStringValueId IN (
        SELECT resultStringValueId 
        FROM  Data_NIIT.dbo.NIIT_ResultStringValues) 
       ) 
+1

なぜあなたはtoResultIntValues、ResultBoolValues、ResultStringValuesとLEFT JOININGをしていませんか?はるかに効率的で本質的に同じであるように思えますし、読みやすく、理解しやすいです。 – pmbAustin

+1

クエリプラン、テーブル定義、それらのテーブルのすべてのインデックスとキーをお願いします。 「*必須のインデックスはすべてのテーブルに存在し、クエリプランは欠落しているインデックス要件を示していません」という誤った結論です。この特定の決定では、クエリプランの推奨事項は完全ではありません。 – RBarryYoung

答えて

0

私の最初の質問です「なぜあなたは一度にこれほど多くのレコードが必要になります?」なぜページングを使用しないのですか?

第2に「with(nolock)」を使用し、「*」は使用しないでください。

第3に、私は左に結合を変更したり、 "Exists clause"を使用します。

SELECT stg.mentioncolumnname,stg.mentioncolumnname1 
    FROM dbo.s_NIIT_ResultValues stg with (nolock) 
where exists(SELECT resultId 
       FROM Data_NIIT.dbo.NIIT_Results with (nolock) 
       where resultId=stg.resultId) 
and exists(

    SELECT resultBoolValueId 
        FROM Data_NIIT.dbo.NIIT_ResultBoolValues with (nolock) 
        where ((stg.resultBoolValueId IS NULL) or (resultBoolValueId=stg.resultBoolValueId)) 
) 
and exists(

    SELECT resultStringValueId 
        FROM Data_NIIT.dbo.NIIT_ResultStringValues with (nolock) 
        where ((stg.resultStringValueId IS NULL) or (resultStringValueId=stg.resultStringValueId)) 
) 

別の方法:テーブルdbo.s_NIIT_ResultValuesとの3つの結合があります。

3つのdiffエディタでdbo.s_NIIT_ResultValuesを持つテーブルを1つだけ結合し、どの結果セットが最小であるかを確認してください。