-1

非常に複雑な SQL ビューがあります。私の問題は、レポートを作成するときに非常に遅く、大量のメモリが必要なことです。ビューが行うこと: 合計値を照会し、係数で乗算します明らかに、多くのサブクエリが含まれているためです... (数えると9)

クエリは、何百万ものデータセットを持つシステムで実行されます。

私の質問。それを最適化するポイントはどこですか?サブクエリのSQLビューを作成するか、準備されたプロシージャを作成すると、より高速になりますか?

SELECT 
    CASE BID WHEN 1 THEN 
        b.TOTAL 
    ELSE 
        (b.TOTAL * - 1) 
    END 
    * 
    CASE WHEN
        (SELECT 
            (CAST(DATEDIFF(day, 
                ISNULL
                ((SELECT dbo.TableA.TimestampFrom + 1 AS start FROM dbo.TableB INNER JOIN
                    dbo.TableA ON dbo.TableB.SID = dbo.TableA.SID
                    WHERE   (dbo.TableB.PID = dbo.TableC.PID) AND
                        (dbo.TableB.MString = 'S' OR dbo.TableB.MString = 'ST') AND
                        (dbo.TableB.TimestampCreated <
                            (SELECT TimestampCreated
                                FROM dbo.TableB AS TableB_2
                            WHERE (RID = dbo.TableC.RID)))
                        AND
                            (dbo.TableB.VPFrom =
                                    (SELECT VPFrom FROM dbo.TableB AS TableB_1
                                            WHERE (RID = dbo.TableC.RID))
                            )), VPFrom), VPTo)
                            AS Float) + 1)
            / 
            (CAST(DATEDIFF(day, start, Vertragsende) AS Float) + 1) AS Faktor

            FROM dbo.TableC
                WHERE (LaufNr = b.LaufNr))
                    > 1 
        THEN 
            1 
        ELSE
            (SELECT (CAST(DATEDIFF(day, 
                ISNULL
                    ((SELECT dbo.TableA.TimestampFrom + 1 AS start FROM dbo.TableB INNER JOIN
                            dbo.TableA ON dbo.TableB.SID =  dbo.TableA.SID
                            WHERE (dbo.TableB.PID = dbo.TableC.PID) AND
                                (dbo.TableB.MString = 'S' OR dbo.TableB.MString = 'ST') AND
                                (dbo.TableB.TimestampCreated <
                                    (SELECT TimestampCreated FROM dbo.TableB AS TableB_2
                                     WHERE (RID = dbo.TableC.RID)))
                                AND (dbo.TableB.VPFrom =
                                    (SELECT VPFrom FROM dbo.TableB AS TableB_1
                                    WHERE (RID = dbo.TableC.RID)))
                        ), VPFrom),VPTo) AS Float) + 1)
                / (CAST(DATEDIFF(day, start, Vertragsende) AS Float) + 1) AS Faktor 
                FROM dbo.TableC
                WHERE (LaufNr = b.LaufNr)) 
        END AS GrossPremium
    ,RID, PID, ONR, OPosLaufNr, LaufNr, bdate
FROM dbo.TableC AS b
4

1 に答える 1

5

索引付けの経験則は次のとおりです。

  • まず、実行計画を読み、

次に、インデックスを追加することを検討してください

  • WHERE 句で使用されるすべての列
  • JOIN 条件で使用されるすべての列、
  • ORDER BY で使用されるすべての列。

場合によっては、複数の単一列インデックスよりも 1 つの複数列インデックスの方が SELECT ステートメントで高速になります。

次に、WHERE 句がsargableであることを確認します。

最後に、サブクエリのいくつかをテスト用のビューに変換してみるのは理にかなっています。私の推測では、問題の根本的な原因は、複数の CASE ステートメントの戻り値に応じて異なるサブクエリを実行していることです。

于 2012-12-18T12:01:45.557 に答える