11

CROSS APPLYパラメータ化されたテーブル値関数に問題があります。単純化された疑似コードの例を次に示します。

SELECT * 
FROM (
    SELECT lor.*
    FROM LOT_OF_ROWS_TABLE lor
    WHERE ...
) AS lor
CROSS APPLY dbo.HeavyTableValuedFunction(lor.ID) AS htvf
INNER JOIN ANOTHER_TABLE AS at ON lor.ID = at.ID 
WHERE ...
  • テーブルの内部選択LOT_OF_ROWS_TABLEが多くの行を返しています。
  • テーブルLOT_OF_ROWS_TABLEを結合し、 ANOTHER_TABLE1 行または数行のみを返します。
  • テーブル値関数は非常に時間がかかり、多くの行を呼び出すと、選択が非常に長く続きます。

私の問題:

この関数は、LOT_OF_ROWS_TABLEjoin だけでデータが制限されるという事実に関係なく、返されるすべての行に対して呼び出されますANOTHER_TABLE

選択は示されている形式でなければなりません - それは生成されますが、実際にははるかに困難です。

書き直そうとすると、非常に高速になる可能性がありますが、次のように書き直すことはできません。

SELECT * 
FROM (
    SELECT lor.*
    FROM LOT_OF_ROWS_TABLE lor
    WHERE ...
) AS lor
INNER JOIN ANOTHER_TABLE AS at ON lor.ID = at.ID 
CROSS APPLY dbo.HeavyTableValuedFunction(at.ID) AS htvf
WHERE ...

知りたい:

最終的に制限された行に対してのみ関数を呼び出すように選択を強制する設定やヒント、または何かがありますか?

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

編集:

テーブル値関数は非常に複雑です: http://pastebin.com/w6azRvxR。私たちが話している選択は、「ユーザーが構成」して生成したものです: http://pastebin.com/bFbanY2n .

4

3 に答える 3

2

このクエリを 2 つの部分に分割して、テーブル変数または一時テーブルのいずれかを使用できます

SELECT lor.*,at.* into #tempresult
FROM (
    SELECT lor.*
    FROM LOT_OF_ROWS_TABLE lor
    WHERE ...
) lor
INNER JOIN ANOTHER_TABLE AS at ON lor.ID = at.ID 
WHERE ...

テーブル値関数である時間のかかる部分を正しく行うようになりました

SELECT  * FROM #tempresult
CROSS APPLY dbo.HeavyTableValuedFunction(#tempresult.ID) AS htvf
于 2013-04-26T12:52:58.617 に答える
0

はいといいえ...サンプルデータの入力と結果の出力がなければ、結果を比較するために達成しようとしていることを解釈するのは困難です。

知りたい:

最終的に制限された行に対してのみ関数を呼び出すように選択を強制する設定やヒント、または何かがありますか?

だから私はあなたの上記の質問に(3年後!!)直接、直接の声明で答えます:

CTE と、CROSS APPLY と INNER JOIN の違い、および CROSS APPLY を使用する必要がある理由について学ぶ必要があります。関数内のコードを「取得」し、CTE を使用して単一の SQL ステートメントに適用できます。

すなわち:

これこれを読んでください。

本質的に、このようなもの...

WITH    t2o AS
        (
        SELECT  t2.*, ROW_NUMBER() OVER (PARTITION BY t1_id ORDER BY rank) AS rn
        FROM    t2
        )
SELECT  t1.*, t2o.*
FROM    t1
INNER JOIN
        t2o
ON      t2o.t1_id = t1.id
        AND t2o.rn <= 3

クエリを適用して、一度だけ必要な日付を推定し、CTE を使用してから、CROSS APPLY を使用して 2 番目の SQL を適用します。

あなたは選択肢がありません。ONE SQL でやろうとしていることはできません。

于 2017-02-02T06:36:08.730 に答える