一時テーブルを作成するストアドプロシージャの最後で一時テーブルを切り捨てるのはなぜですか?


12

SQL Serverは、ストアドプロシージャ内で作成された一時テーブルをキャッシュし、プロシージャが終了してその後実行されるときにそれらの名前を変更するだけです。私の質問は、tempdbスペースがいつ解放されるかに関するものです。手順の最後でテーブルが切り捨てられることを読みました。これはセッションごとに処理されることをコメントで読んでおり、クリーンアップが必要かどうかについての質問がMSDNで回答されています。しかし、同じセッションで2回実行されない場合はどうでしょうか?

また、テーブルが範囲外になるとその領域を解放するバックグラウンドガベージコレクションプロセスがあることも聞いたことがあります。

それを作成するストアドプロシージャの最後で一時テーブルを切り捨てると、逆の期待にもかかわらず、truncateステートメントが使用されていない場合よりも、テーブルがtempdbでデータ用に使用するスペースがより速く解放されるようです。どうして?

そのような切り捨てステートメントを使用するかどうかの相対的なパフォーマンスへの影響はどうなりますか?SNAPSHOT分離を使用する場合、tempdbにストレスがかかることがよくあります。tempdbで使用されているスペースをできるだけ大きなtempテーブルからできるだけ早く解放すると、tempdbの不必要な増大を防ぐことができると思います。この潜在的なスペース節約は、パフォーマンスを犠牲にして実現されるでしょうか?

以下に、問題を再現するためのコードを示します(主に@TheGameiswarから、いくつかの変更を加えたものです)。

SET NOCOUNT ON;
GO
ALTER PROC usp_test
AS
BEGIN
    IF object_id('tempdb..#temp') IS NOT NULL
        DROP TABLE #temp

    SELECT *
    INTO #temp
    FROM [dbo].[Event_28] -- This is a table with 15313 rows, using 35648 KB according to sp_spaceused

    --SELECT SUM(user_object_reserved_page_count) AS [user object pages used]
    --  ,(SUM(user_object_reserved_page_count) * 1.0 / 128) AS [user object space in MB]
    --  ,getdate() AS BeforeTruncate
    --FROM tempdb.sys.dm_db_file_space_usage;
 --   TRUNCATE TABLE #temp
    --SELECT SUM(user_object_reserved_page_count) AS [user object pages used]
    --  ,(SUM(user_object_reserved_page_count) * 1.0 / 128) AS [user object space in MB]
    --  ,getdate() AS AfterTruncate
    --FROM tempdb.sys.dm_db_file_space_usage;

END
GO

SELECT SUM(user_object_reserved_page_count) AS [user object pages used]
    ,(SUM(user_object_reserved_page_count) * 1.0 / 128) AS [user object space in MB]
    ,getdate() AS 'before'
FROM tempdb.sys.dm_db_file_space_usage;

EXEC usp_test
GO

SELECT SUM(user_object_reserved_page_count) AS [user object pages used]
    ,(SUM(user_object_reserved_page_count) * 1.0 / 128) AS [user object space in MB]
    ,getdate() AS 'final'
FROM tempdb.sys.dm_db_file_space_usage;
GO 40

コメントされた行は、一部の実行ではコメント化され、他の実行ではコメント化されません。TRUNCATEがコメントアウトされたとき、tempdb.sys.dm_db_file_space_usageクエリの結果(さらに4472ページ、34.9375 MB大きい)がプロシージャが実行される前に結果と一致するまで2.25から4.5秒かかりました。行(を含むTRUNCATE)のコメントを外すと、約0.11〜0.9秒しかかかりませんでした。これらの結果はライブシステムからのものであり、この実験中にソーステーブルのデータが若干増加します。

コードがコメントアウトされたサンプル出力(最初から最後の「最終」エントリから2.69秒):

user object pages used user object space in MB                 before
---------------------- --------------------------------------- -----------------------
1536                   12.000000                               2017-10-04 21:03:42.197

Beginning execution loop
user object pages used user object space in MB                 final
---------------------- --------------------------------------- -----------------------
6000                   46.875000                               2017-10-04 21:03:42.423

user object pages used user object space in MB                 final
---------------------- --------------------------------------- -----------------------
6000                   46.875000                               2017-10-04 21:03:42.533

user object pages used user object space in MB                 final
---------------------- --------------------------------------- -----------------------
6000                   46.875000                               2017-10-04 21:03:42.643

user object pages used user object space in MB                 final
---------------------- --------------------------------------- -----------------------
6000                   46.875000                               2017-10-04 21:03:42.883

user object pages used user object space in MB                 final
---------------------- --------------------------------------- -----------------------
6000                   46.875000                               2017-10-04 21:03:42.990

user object pages used user object space in MB                 final
---------------------- --------------------------------------- -----------------------
6000                   46.875000                               2017-10-04 21:03:43.100

user object pages used user object space in MB                 final
---------------------- --------------------------------------- -----------------------
6000                   46.875000                               2017-10-04 21:03:43.450

user object pages used user object space in MB                 final
---------------------- --------------------------------------- -----------------------
6000                   46.875000                               2017-10-04 21:03:43.650

user object pages used user object space in MB                 final
---------------------- --------------------------------------- -----------------------
6000                   46.875000                               2017-10-04 21:03:43.767

user object pages used user object space in MB                 final
---------------------- --------------------------------------- -----------------------
6000                   46.875000                               2017-10-04 21:03:43.993

user object pages used user object space in MB                 final
---------------------- --------------------------------------- -----------------------
6000                   46.875000                               2017-10-04 21:03:44.103

user object pages used user object space in MB                 final
---------------------- --------------------------------------- -----------------------
6000                   46.875000                               2017-10-04 21:03:44.213

user object pages used user object space in MB                 final
---------------------- --------------------------------------- -----------------------
6000                   46.875000                               2017-10-04 21:03:44.437

user object pages used user object space in MB                 final
---------------------- --------------------------------------- -----------------------
6000                   46.875000                               2017-10-04 21:03:44.553

user object pages used user object space in MB                 final
---------------------- --------------------------------------- -----------------------
6000                   46.875000                               2017-10-04 21:03:44.663

user object pages used user object space in MB                 final
---------------------- --------------------------------------- -----------------------
6000                   46.875000                               2017-10-04 21:03:44.887

user object pages used user object space in MB                 final
---------------------- --------------------------------------- -----------------------
6000                   46.875000                               2017-10-04 21:03:45.003

user object pages used user object space in MB                 final
---------------------- --------------------------------------- -----------------------
1536                   12.000000                               2017-10-04 21:03:45.113

コードがコメント化されていないサンプル結果(最初から最後の「最終」エントリから0.11秒):

user object pages used user object space in MB                 before
---------------------- --------------------------------------- -----------------------
1536                   12.000000                               2017-10-04 21:07:39.807

user object pages used user object space in MB                 BeforeTruncate
---------------------- --------------------------------------- -----------------------
6016                   47.000000                               2017-10-04 21:07:39.923

user object pages used user object space in MB                 AfterTruncate
---------------------- --------------------------------------- -----------------------
6016                   47.000000                               2017-10-04 21:07:39.923

Beginning execution loop
user object pages used user object space in MB                 final
---------------------- --------------------------------------- -----------------------
6016                   47.000000                               2017-10-04 21:07:40.160

user object pages used user object space in MB                 final
---------------------- --------------------------------------- -----------------------
1536                   12.000000                               2017-10-04 21:07:40.270

回答:


12

それを作成するストアドプロシージャの最後で一時テーブルを切り捨てると、逆の期待にもかかわらず、truncateステートメントが使用されていない場合よりも、テーブルがtempdbでデータ用に使用するスペースがより速く解放されるようです。どうして?

一時テーブルが十分に大きい(128エクステントを超える)場合、物理ページの割り当て解除は延期され、バックグラウンドシステムタスクによって実行されます。これは、明示TRUNCATE TABLEが使用されるかどうかに関係なく当てはまります。

唯一の違いは、小さな実装の詳細です。明示はTRUNCATE TABLEしてタスクを作成するために起こる短いタイマーの一時表のクリーンアップが作成した(それ以外は同一の)繰延ドロップタスクより:

人々が好きだからコールスタック

これが偶然によるものなのか、設計によるものなのかは誰でも推測できます。もちろん、このレベルの詳細はサポートされている製品の表面積を超えているため、いつでも変更できます。

(ほとんど)文書化されていないトレースフラグを使用して、遅延ドロップをグローバルに無効にした場合:

DBCC TRACEON (671, -1);

...割り当て解除は両方のケースで同期的に実行され、タイミングに違いは見られません。

そのような切り捨てステートメントを使用するかどうかの相対的なパフォーマンスへの影響はどうなりますか?SNAPSHOT分離を使用する場合、tempdbにストレスがかかることがよくあります。tempdbで使用されているスペースをできるだけ大きなtempテーブルからできるだけ早く解放すると、tempdbの不必要な増大を防ぐことができると思います。この潜在的なスペース節約は、パフォーマンスを犠牲にして実現されるでしょうか?

私はこれがどちらの方法でも大きな違いを生むことを真剣に疑っています。場合はtempdbのは、 1秒または3が問題ではないはず後に延期ドロップが発生するかどうか、ワークロードのピークのニーズに適切な大きさ。同じ作業が行われます。タイミングのわずかな違いです。

一方TRUNCATE TABLE、ストアドプロシージャの最後にある一時テーブルでの使用をより快適に感じる場合は、それを使用してください。私はこれを行うことの特定の欠点を認識していません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.