エイリアス化された式ごとに個別の CROSS APPLY を使用するか、可能であれば同じ CROSS APPLY で複数の式を定義する必要がありますか?
コードで生成される多くの非常に複雑な SQL クエリ (多くの場合、12 の JOIN を含む 4 ~ 5 ページの長さ) をリファクタリングしています。一部のパーツはさまざまな状況で再利用されるため、多くの場合、クエリは 5 つか 6 つの深さでネストされます。クエリをネストする一般的な理由は、1 つのクエリがいくつかの値を抽出し、計算を実行し、その値にエイリアスを割り当てるためです。次に、囲んでいるクエリは、エイリアス値などを使用してさらに計算を行います。これが必要なのは、エイリアス化された式は、それを定義するクエリの他の場所では参照できず、外側のクエリでのみ参照できるためです。(コードにも存在する別の方法は、同じ長い部分式をクエリ全体で数十回繰り返すことです。)
このスパゲッティ SQL を簡素化するために、CROSS APPLY を使用してこれらのテレスコープ クエリを折りたたみ始めました。CROSS APPLY を使用すると、エイリアスを割り当てて、同じクエリ内の別の場所で使用できます。CROSS APPLY 句のいずれも、副選択を介して新しいテーブルを導入したり、UDF を呼び出したりしないことに注意してください。
最初は、同じ CROSS APPLY に多くの式を入れました。ただし、私のコードはモジュール化する必要があります。ユーザーはフィルター用にフィールドを選択でき、さまざまな列に対して同様の統計を生成するため、さまざまな状況でさまざまなフィールドが必要になります。したがって、互いに少しだけ異なる多くの同様のクエリが作成されます。一部のフィールドは他のフィールドの上に構築され、一部はクエリで以前に定義された特定の JOIN に依存しているため、すべてを同じ CROSS APPLY に入れることはできません。したがって、CROSS APPLY の数は異なる場合があります。
さらに、抽出された一部のフィールドは、新しいエイリアスによって隠蔽され、再定義されます (通常、NULL を削除したり、デフォルトを指定したりするため)。したがって、CROSS APPLY で定義されたフィールドが他の場所で参照される場合、CROSS APPLY のテーブル エイリアスを指定する必要があります。あいまいさを取り除きます。
これの結論は、CROSS APPLY に論理的な名前を付ける必要があり、パフォーマンスに関心があるということです。CROSS APPLY の数が変更された場合、CROSS APPLY が単純なカウンター (computed1、computed2 など) で番号付けされている場合、特定のフィールドの名前参照がcomputer3.[FIELD NAME] からcomputer4.[FIELD] に変更される場合があります。 NAME] は、クエリの残りの部分全体に波及効果をもたらします。これは、異なる C# プロシージャへの呼び出しによって組み立てられた可能性があります。これはメンテナンスの問題です。
私が検討している代替案は、計算された各式を個別の CROSS APPLY に配置することです。CROSS APPLY の名前は、式のエイリアスから派生します。例えば:
1 つの CROSS APPLY を使用する:
CROSS APPLY (
SELECT
[TIV_BLDG] = (CASE [COVERAGE] WHEN 'TIV_BLDG' THEN VALUEAMT ELSE 0 END)
, [TIV_OSTR] = (CASE [COVERAGE] WHEN 'TIV_OSTR' THEN VALUEAMT ELSE 0 END)
, [TIV_CONT] = (CASE [COVERAGE] WHEN 'TIV_CONT' THEN VALUEAMT ELSE 0 END)
, [TIV_TIME] = (CASE [COVERAGE] WHEN 'TIV_TIME' THEN VALUEAMT ELSE 0 END)
) computed2
4 つの CROSS APPLY を使用する:
CROSS APPLY (SELECT [TIV_BLDG] = (CASE [COVERAGE] WHEN 'TIV_BLDG' THEN VALUEAMT ELSE 0 END)) AS [TIV_BLDG_COMP]
CROSS APPLY (SELECT [TIV_OSTR] = (CASE [COVERAGE] WHEN 'TIV_OSTR' THEN VALUEAMT ELSE 0 END)) AS [TIV_OSTR_COMP]
CROSS APPLY (SELECT [TIV_CONT] = (CASE [COVERAGE] WHEN 'TIV_CONT' THEN VALUEAMT ELSE 0 END)) AS [TIV_CONT_COMP]
CROSS APPLY (SELECT [TIV_TIME] = (CASE [COVERAGE] WHEN 'TIV_TIME' THEN VALUEAMT ELSE 0 END)) AS [TIV_TIME_COMP]
この複数の CROSS APPLY アプローチを使用すると、新しい適用を追加したり削除したりしても変更されない名前を簡単に生成でき、フィールドを参照するコードでテーブル エイリアスがどうなるかを予測できます。ただし、これはより多くの CROSS APPLY ステートメントを意味します。パフォーマンスへの影響は何ですか? CROSS APPLY またはその他の SQL Server 機能を使用して、これを行うためのより良い方法はありますか? (クロスデータベースである必要はないので、Microsoft のみの機能で問題ありません。)