Perché il troncamento di una tabella temporanea alla fine della procedura memorizzata che crea spazio tempdb libero più velocemente?


12

SQL Server memorizza nella cache le tabelle temporanee create all'interno di stored procedure e le rinomina semplicemente al termine della procedura e successivamente viene eseguita. La mia domanda ha a che fare con il rilascio dello spazio tempdb. Ho letto che la tabella viene troncata alla fine della procedura . Ho letto nei commenti che questo è gestito su una base per sessione e ho visto una domanda sull'opportunità o meno di una pulizia su MSDN . Ma cosa succede se non viene mai eseguito dalla stessa sessione due volte?

Ho anche sentito che esiste un processo di garbage collection in background che libera lo spazio una volta che la tabella è fuori portata.

Troncare una tabella temporanea al termine della procedura memorizzata che la crea sembra causare lo spazio che la tabella utilizza in tempdb per i dati da rilasciare più velocemente rispetto a quando non viene utilizzata alcuna istruzione troncata, nonostante le aspettative contrarie. Perché?

Quali sarebbero le implicazioni relative alle prestazioni dell'utilizzo o meno di un'istruzione così troncata? Quando si utilizza l'isolamento SNAPSHOT, tempdb è spesso stressato e penso che il rilascio dello spazio utilizzato in tempdb da una tabella temporanea di grandi dimensioni non appena possibile impedirebbe una crescita altrimenti inutile di tempdb. Questo potenziale risparmio di spazio verrebbe a scapito delle prestazioni?

Ecco del codice per riprodurre il problema (principalmente da @TheGameiswar, con alcune modifiche):

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

Le righe commentate sono state lasciate commentate per alcune tirature e non commentate per altre. Quando il TRUNCATEcommento è stato commentato, ci sono voluti tra 2,25 e 4,5 secondi prima che i risultati della tempdb.sys.dm_db_file_space_usagequery (4472 più pagine e 34.9375 MB più grandi) corrispondessero al risultato prima dell'esecuzione della procedura. Con le righe (incluso il TRUNCATE) non commentate, ci sono voluti solo circa 0,11 - 0,9 secondi. Questi risultati provengono da un sistema attivo, con una lieve crescita dei dati nella tabella di origine durante questo esperimento.

Esempio di output con il codice commentato (2,69 secondi dalla prima all'ultima voce "finale"):

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

Risultati di esempio con il codice non commentato (0,11 secondi dalla prima all'ultima voce "finale"):

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

Risposte:


12

Troncare una tabella temporanea al termine della procedura memorizzata che la crea sembra causare lo spazio che la tabella utilizza in tempdb per i dati da rilasciare più velocemente rispetto a quando non viene utilizzata alcuna istruzione troncata, nonostante le aspettative contrarie. Perché?

Se la tabella temporanea è abbastanza grande ( più di 128 estensioni ), le deallocazioni di pagine fisiche vengono rinviate ed eseguite da un'attività di sistema in background. Questo è vero se TRUNCATE TABLEviene usato o meno un esplicito .

L'unica differenza è un piccolo dettaglio di implementazione. Un esplicito TRUNCATE TABLEaccade per creare un'attività con un timer più breve rispetto all'attività di rilascio differito (altrimenti identica) creata dalla pulizia temporanea della tabella:

Call stack perché alla gente piacciono

Se questo è per caso o design è un'ipotesi di chiunque. Naturalmente potrebbe cambiare in qualsiasi momento, poiché questo livello di dettaglio va ben oltre la superficie del prodotto supportata.

Se disabiliti il ​​drop differito a livello globale con un flag di traccia (principalmente) non documentato:

DBCC TRACEON (671, -1);

... le deallocazioni vengono eseguite in modo sincrono in entrambi i casi e non vedrai alcuna differenza nei tempi.

Quali sarebbero le implicazioni relative alle prestazioni dell'utilizzo o meno di un'istruzione così troncata? Quando si utilizza l'isolamento SNAPSHOT, tempdb è spesso stressato e penso che il rilascio dello spazio utilizzato in tempdb da una tabella temporanea di grandi dimensioni non appena possibile impedirebbe una crescita altrimenti inutile di tempdb. Questo potenziale risparmio di spazio verrebbe a scapito delle prestazioni?

Dubito seriamente che ciò farebbe molta differenza in entrambi i modi. Se tempdb è dimensionato in modo appropriato in base alle esigenze di picco del carico di lavoro, non dovrebbe importare se si verifica una caduta differita dopo uno o tre secondi. Lo stesso lavoro è fatto; è solo una piccola differenza nei tempi.

D'altra parte: se ti senti più a tuo agio nell'utilizzare TRUNCATE TABLEtabelle temporanee alla fine delle procedure memorizzate, procedi con quello. Non sono a conoscenza di alcun aspetto negativo particolare nel fare questo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.