0

同じクエリ内の異なる入力変数に対して、同じテーブル関数を使用して数回結合したいと考えています。しかし、これは私の場合、テーブル変数を使用してテーブル関数から個別に選択するよりもはるかに遅いことがわかりました。

テーブル変数を回避しながら高速クエリを実行するにはどうすればよいですか?

たとえば、次のような SQL クエリがあります。

SELECT P.プロジェクト名、A.番号、B.番号
FROM プロジェクト AS P
LEFT JOIN dbo.fn_ProjectNumber(@dateA) AS A
    ON P.ProjectID = A.ProjectID
左結合 dbo.fn_ProjectNumber(@dateB) AS B
    ON P.ProjectID = B.ProjectID

ただし、関数から個別に変数を選択し、後で結合するよりもはるかに遅くなります。次に例を示します。

@tempA に挿入
SELECT P.ProjectID、A.Number
FROM プロジェクト AS P
LEFT JOIN dbo.fn_ProjectNumber(@dateA) AS A
    ON P.ProjectID = A.ProjectID

@tempB に挿入
SELECT P.ProjectID、B.Number
FROM プロジェクト AS P
左結合 dbo.fn_ProjectNumber(@dateB) AS B
    ON P.ProjectID = B.ProjectID

SELECT P.プロジェクト名、A.番号、B.番号
FROM プロジェクト AS P
左 JOIN @tempA AS A
    ON P.ProjectID = A.ProjectID
左結合 @tempA AS B
    ON P.ProjectID = B.ProjectID

これの原因は何ですか?高速なクエリを取得し、テーブル変数を回避する方法はありますか?


詳細:

これは私がやっていることと似た例にすぎませんが、関数fn_ProjectNumber(@date datetime)には4つのテーブル間の結合のようなものが含まれます...


    
4

4 に答える 4

1

結合を修正してみてください。2 番目の LEFT JOIN で間違ったエイリアスを参照しています。

オリジナル:

SELECT P.ProjectName, A.Number, B.Number
FROM Project AS P
LEFT JOIN dbo.fn_ProjectNumber(@dateA) AS A
    ON P.ProjectID = A.ProjectID
LEFT JOIN dbo.fn_ProjectNumber(@dateB) AS B
    ON P.ProjectID = A.ProjectID

修繕:

SELECT P.ProjectName, A.Number, B.Number
FROM Project AS P
LEFT JOIN dbo.fn_ProjectNumber(@dateA) AS A
    ON P.ProjectID = A.ProjectID
LEFT JOIN dbo.fn_ProjectNumber(@dateB) AS B
    ON P.ProjectID = B.ProjectID --<<<<<
于 2009-09-29T13:36:24.410 に答える
1

テーブル変数を避けようとしている特別な理由はありますか? これらは優れた最適化手法であり、一時オブジェクトをクリーンアップする必要はありません。

とにかく、そのようにしたくない場合は、いつでも試すことができます

SELECT
    P.ProjectID, A.Number, B.Number
FROM
    Project AS P
        LEFT JOIN
            (SELECT P.ProjectID, A.Number
            FROM Project AS P
            LEFT JOIN dbo.fn_ProjectNumber(@dateA) AS A
               ON P.ProjectID = A.ProjectID
            ) AS A
                ON P.ProjectID = A.ProjectID
        LEFT JOIN
            (SELECT P.ProjectID, B.Number
            FROM Project AS P
            LEFT JOIN dbo.fn_ProjectNumber(@dateB) AS B
                ON P.ProjectID = B.ProjectID
            ) AS B
                ON P.ProjectID = B.ProjectID
于 2009-09-29T13:37:10.183 に答える
1

サンプル クエリでは、テーブル Project の行ごとに各関数を 1 回呼び出しているため、結合が遅くなります。関数を 1 回呼び出すだけなので、一時テーブルの方が高速です。

一時テーブルを回避する 1 つの方法は、CTE を使用することです (一般的なテーブル式 - 再帰だけでなく、SQL 2005 以降で使用可能)。一般的な構文は次のようになります。

WITH cteTempName (<list of columns>)
 as (<your table function call>)
 SELECT <your query here, with "cteTempName" appearing as just another table to select from>
于 2009-09-29T14:02:48.900 に答える
0

一緒に結合されるテーブル間の関係を定義していないため、結合が遅くなる可能性がありますか? SQL Server でのクエリのパフォーマンスについてはよくわかりませんが、関係を定義すると結合のパフォーマンスが向上します。

于 2009-09-29T13:35:33.557 に答える