2

特定の日時(つまり、2012年5月1日から2012年5月31日まで)のデータベースで複雑なクエリのリストを実行しています。次に、2012年6月1日から2012年6月30日まで同じクエリを実行する必要があります。次に、レポートの目的で結果を結合します。

クエリでは、一時データを保持するためにいくつかのテーブル変数を使用しました。データベースが大きいため、テーブル変数のサイズも大きくなります。これらのテーブル変数を再利用する方法はありますか?

DROP、Truncateは機能しません。@tableからすべてのデータを削除する必要がありますか?もしそうなら、それは遅いでしょうか?@tableには大量のデータがあるため、バッチ削除を行う必要がありますか?

ところで、私はすべてのクエリを1つのSPファイルに入れる必要があり、システムの設計方法が原因で関数や他のSPを呼び出すことができません。

ありがとう

=============================

クエリにループはありません。それは次のように機能します:

select ..... select ..... update ..... join ..... ..

2012年5月1日から2012年5月31日までの一連のクエリを実行します。次に、2012年6月1日から2012年6月30日までの同じクエリセットを実行する必要があります。

クエリには多くの論理的な内部があるため、これら2つを1つのクエリセットに結合することはできません。システムが設計されているため、クエリの関数またはSPを呼び出すことはできません。最初のクエリセットを実行してから、2番目のクエリセットを順番に実行する必要があります。

問題は、データが多すぎること、@tableが大きすぎることです。@tableを再利用できれば、問題は解決します。

ありがとう

===============================

はい、今、同じコードで、2つの異なる日時間隔で2回繰り返します。ただし、コードでは、日時の違いに基づいて、論理的な内部の異なるプロセスがあります。申し訳ありませんが、実際のコードを投稿することはできません。ただし、このプロセスは、パラメータとして異なる日時を持つSPのようなものです。

ただし、この場合はSP / functionを使用できないため、同じコードを2回ハードコーディングする必要があります。理想的には、コードを繰り返すたびに異なる@tableを使用する必要があります(現在、3回繰り返す必要があります)が、データサイズのため、3回繰り返すと@tableが大きすぎます(それぞれに複数の@tableが必要です)論理的な部分を行うため)。

多分私は一時的なテーブルを使用したほうがいいですか?だから私は新しい「リピート」を始めるときにそれを落とすことができますか?

ありがとう

4

2 に答える 2

15

テーブル変数は現在のデータベースに記録されておらず、トランザクションの対象ではありません。切り捨てまたはドロップが削除よりも速いのはなぜだと思いますか? これを試しましたか?

DECLARE @f TABLE(id INT);

INSERT @f SELECT 1;

BEGIN TRANSACTION;
DELETE @f WHERE id = 1;
ROLLBACK TRANSACTION;

SELECT id FROM @f;

結果がありません。ここで、削除が現在のデータベースに完全に記録されている場合 (これが通常のユーザー テーブルDELETEよりも遅くなる原因です)、がロールバックされ、 がデータを返すはずです。いいえ、削除はトランザクションの一部ではありません。したがって、後者が許可されていれば、 と は同一ではないにしても、非常に似ていると論理的に結論付けることができます。TRUNCATEDELETESELECTDELETETRUNCATE

テーブル変数を使用する必要がある場合は、削除を使用してください。遅いと感じた場合、おそらく削除が原因ではなく、セットベースの操作を使用するのではなく、ループでテーブル変数を再利用していることが原因である可能性があります。しかしもちろん、2 つの異なる @table 変数を使用した場合と、単一のテーブル変数を再使用してその間に削除を発行した場合のコードの速度がどれだけ遅くなるかをテストするには、私たちの誰よりもあなたの方が適しています。しかし、多くのレベルで最適とは思えないため、プロセス全体を再調査する必要があると思います。

于 2012-07-23T21:45:50.260 に答える
1

確かに、しかし本当に必要なのはテーブル パラメータではなく、代わりに一時テーブルが必要です。

CREATE TABLE #my_temp_table (column1 int, column2 varchar(max), ...)
INSERT INTO #my_temp_table (column1, column2) VALUES (...)
-- Use the temporary table here
DELETE FROM #my_temp_table
INSERT INTO #my_temp_table (column1, column2) VALUES (...)
-- Use the temporary table again
DROP TABLE #my_temp_table

編集: サブミッターは、「フラグ READONLY を使用してストアド プロシージャに渡されるため、テーブル変数を使用できません」と言っている可能性があります。その場合、彼はそれを一時テーブルに変換することでいくらかのマイレージを得ることができます。

補足として、SQL Server のドキュメントではそうではないと主張していますが、一時テーブルがテーブル変数よりも優れたパフォーマンスを発揮する例を見てきました。これは、TEMPDB を別のディスクに配置したためだと思います。このディスクには、利用可能な IO 容量がたくさんありました。

ただし、一時テーブルには名前付けの問題があることに注意してください。一時テーブルの名前の競合を作成しようとすると、ストアド プロシージャがロックされる可能性があります。テーブル変数はその問題に悩まされません。

于 2012-07-23T21:46:50.430 に答える