Mengapa memotong tabel temp di akhir prosedur tersimpan yang membuatnya menjadi ruang tempdb lebih cepat?

12

SQL Server cache tabel temp yang dibuat dalam prosedur tersimpan dan hanya mengubah nama mereka ketika prosedur berakhir dan selanjutnya dijalankan. Pertanyaan saya berkaitan dengan kapan ruang tempdb dirilis. Saya sudah membaca bahwa tabel terpotong di akhir prosedur . Saya telah membaca di komentar bahwa ini ditangani berdasarkan per sesi dan melihat pertanyaan tentang apakah pembersihan perlu dijawab pada MSDN . Tetapi bagaimana jika itu tidak pernah dieksekusi oleh sesi yang sama dua kali?

Saya juga pernah mendengar bahwa ada proses pengumpulan sampah latar belakang yang membebaskan ruang itu begitu tabel berada di luar ruang lingkup.

Memotong tabel temp pada akhir prosedur tersimpan yang membuatnya tampaknya menyebabkan ruang tabel menggunakan tempdb untuk data yang akan dirilis lebih cepat daripada jika tidak ada pernyataan truncate digunakan, meskipun harapan sebaliknya. Mengapa?

Apa implikasi kinerja relatif dari menggunakan atau tidak menggunakan pernyataan terpotong seperti itu? Saat menggunakan isolasi SNAPSHOT, tempdb sering ditekankan dan saya akan berpikir bahwa melepaskan ruang yang digunakan dalam tempdb dari tabel temp besar sesegera mungkin akan mencegah pertumbuhan tempdb yang tidak perlu. Apakah penghematan ruang potensial ini akan mengorbankan kinerja?

Berikut adalah beberapa kode untuk mereproduksi masalah (kebanyakan dari @TheGameiswar, dengan beberapa perubahan):

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

Baris yang dikomentari dibiarkan dikomentari untuk beberapa putaran dan tidak dikomentari untuk yang lain. Ketika TRUNCATEdikomentari, butuh antara 2,25 dan 4,5 detik sebelum hasil tempdb.sys.dm_db_file_space_usagekueri (4472 halaman lebih banyak dan 34,9375 MB lebih besar) cocok dengan hasilnya sebelum prosedur dieksekusi. Dengan baris (termasuk TRUNCATE) tidak dikomentari, hanya butuh sekitar 0,11 - 0,9 detik. Hasil ini berasal dari sistem langsung, dengan beberapa pertumbuhan data kecil dalam tabel sumber selama percobaan ini.

Contoh output dengan kode berkomentar (2,69 detik dari entri "final" pertama hingga terakhir):

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

Contoh hasil dengan kode tidak dikomentari (0,11 detik dari entri "final" pertama hingga terakhir):

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
Mark Freeman
sumber

Jawaban:

12

Memotong tabel temp pada akhir prosedur tersimpan yang membuatnya tampaknya menyebabkan ruang tabel menggunakan tempdb untuk data yang akan dirilis lebih cepat daripada jika tidak ada pernyataan truncate digunakan, meskipun harapan sebaliknya. Mengapa?

Jika tabel sementara cukup besar ( lebih dari 128 extents ), deallokasi halaman fisik ditunda, dan dilakukan oleh tugas sistem latar belakang. Ini benar apakah eksplisit TRUNCATE TABLEdigunakan atau tidak.

Satu-satunya perbedaan adalah detail implementasi yang sangat kecil. Terjadi secara eksplisit TRUNCATE TABLEuntuk membuat tugas dengan penghitung waktu yang lebih pendek daripada tugas penurunan yang ditunda (yang identik) yang dibuat oleh pembersihan tabel sementara:

Sebut tumpukan karena orang-orang menyukainya

Apakah ini kebetulan atau desain adalah dugaan siapa pun. Tentu saja dapat berubah kapan saja, karena tingkat detail ini jauh melampaui area permukaan produk yang didukung.

Jika Anda menonaktifkan drop yang ditangguhkan secara global dengan bendera jejak (kebanyakan) yang tidak didokumentasikan:

DBCC TRACEON (671, -1);

... deallocations dilakukan secara sinkron dalam kedua kasus, dan Anda tidak akan melihat perbedaan waktu.

Apa implikasi kinerja relatif dari menggunakan atau tidak menggunakan pernyataan terpotong seperti itu? Saat menggunakan isolasi SNAPSHOT, tempdb sering ditekankan dan saya akan berpikir bahwa melepaskan ruang yang digunakan dalam tempdb dari tabel temp besar sesegera mungkin akan mencegah pertumbuhan tempdb yang tidak perlu. Apakah penghematan ruang potensial ini akan mengorbankan kinerja?

Saya sangat meragukan hal ini akan membuat banyak perbedaan. Jika tempdb diukur sesuai dengan kebutuhan puncak beban kerja Anda, apakah penurunan yang ditunda terjadi setelah satu detik atau tiga tidak menjadi masalah. Pekerjaan yang sama dilakukan; itu hanya perbedaan kecil dalam hal waktu.

Di sisi lain: Jika Anda merasa lebih nyaman menggunakan TRUNCATE TABLEtabel sementara di akhir prosedur tersimpan Anda, ikuti itu. Saya tidak mengetahui adanya kelemahan khusus untuk melakukan ini.

Paul White 9
sumber