1

かなり大きなテーブルで機能するいくつかの自己結合を使用した、比較的複雑なクエリがあります。したがって、そのクエリをより高速に実行するには、データのサブセットのみを操作する必要があります。上記のデータのサブセットは、渡されたパラメータに応じて12000〜120000行の範囲になります。

詳細については、こちらをご覧ください:自己結合で参照されるSQLServerCTEの速度が遅い

ご覧のとおり、以前はCTEを使用してデータサブセットを返していました。これにより、SQL Serverが1回実行してデータセットを再利用するのではなく、結合ごとにCTEでSelectステートメントを再実行するため、パフォーマンスの問題が発生しました。

別の方法として、一時テーブルを使用すると、はるかに高速に機能しました(UDF本体の外部にある別のウィンドウでクエリをテストしている間)。ただし、これをマルチステートメントUDFに実装しようとすると、SQL Serverから、マルチステートメントUDFが何らかの理由で一時テーブルをサポートしていないことを強く思い出しました...

UDFはテーブル変数を許可するので、それを試しましたが、CTEバージョンでは40秒しかかからなかったのに対し、クエリが完了するまでに1分40秒かかるため、パフォーマンスは非常にひどいものです。このスレッドにリストされている理由により、テーブル変数が遅いと思います。SQLServerストアドプロシージャへの挿入時にテーブル変数のパフォーマンスが低下する

一時テーブルのバージョンは約1秒かかりますが、SQL Serverの制限により関数にできず、テーブルを呼び出し元に戻す必要があります。

CTEとテーブル変数の両方が遅すぎて、一時テーブルがUDFで拒否されることを考えると、UDFを迅速に実行するためのオプションは何ですか?

よろしくお願いします。

4

3 に答える 3

3

多くの場合、これらのテーブル変数の主キーを宣言するだけでよく、これも高速です。

于 2010-06-16T18:41:53.927 に答える
1

プロセス キー テーブルを設定して使用します。アーランド ソマースコグによるストアド プロシージャ間でデータを共有する方法の記事を参照してください。

于 2010-06-16T18:42:04.073 に答える
0

私が使用した 1 つの厄介な回避策には、次のようなコードが含まれます (疑似コードが続きます)。

CREATE TEMP TABLE #foo

EXECUTE MyStoredProcedure

SELECT *
 from #foo

GO

--  Stored procedure definition
CREATE PROCEDURE MyStoredProcedure
AS

INSERT #foo values (whatever)

RETURN
GO

つまり、ストアド プロシージャは、呼び出し元のプロシージャ (またはルーチン) によって作成された一時テーブルを参照して使用します。これは機能しますが、明確に文書化しないと、他の人が何が起こっているのかを理解するのを混乱させる可能性があり、再コンパイル、統計の再計算、および不要なクロックサイクルを消費する可能性のあるその他の奇妙なことが発生します。

于 2010-06-16T18:25:20.207 に答える