Чому обрізка темп-таблиці в кінці збереженої процедури створює її вільний простір tempdb швидше?


12

SQL Server кешує тимчасові таблиці, створені в межах збережених процедур, і просто перейменовує їх, коли процедура закінчується і згодом виконується. Моє запитання пов'язане з тим, коли буде випущено простір tempdb. Я читав, що таблиця обрізана в кінці процедури . Я читав в коментарях, що це обробляється на сеансі, і бачив питання про те, чи потрібно очищення, відповів на MSDN . Але що робити, якщо він ніколи не виконується одним і тим же сеансом двічі?

Я також чув, що існує фоновий процес збору сміття, який звільняє цей простір, коли таблиця не виходить за межі.

Обрізання темп-таблиці в кінці збереженої процедури, що створюється, здається, викликає простір, який таблиця використовує в tempdb, щоб дані вивільнялися швидше, ніж якщо не використовується жодна операція скорочення, незважаючи на очікування протилежного. Чому?

Які будуть відносні наслідки для використання або використання такого оператора усікання? Використовуючи ізоляцію SNAPSHOT, tempdb часто підкреслюється, і я думаю, що звільнення простору, який використовується у tempdb, з великої темп-таблиці як можна швидше запобіжить непотрібне зростання 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було прокоментовано, пройшло від 2,25 до 4,5 секунд, перш ніж результати tempdb.sys.dm_db_file_space_usageзапиту (на 4472 більше сторінок і на 34,9375 Мб більше) відповідали результату перед виконанням процедури. Якщо рядки (включаючи 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

Обрізання темп-таблиці в кінці збереженої процедури, що створюється, здається, викликає простір, який таблиця використовує в tempdb, щоб дані вивільнялися швидше, ніж якщо не використовується жодна операція скорочення, незважаючи на очікування протилежного. Чому?

Якщо тимчасова таблиця достатньо велика ( більше 128 розширень ), фізичні розгортання сторінки відкладаються та виконуються фоновим системним завданням. Це вірно, використовується явна TRUNCATE TABLEчи ні.

Єдина відмінність - крихітна деталь реалізації. Явна TRUNCATE TABLEситуація створює завдання з коротшим таймером, ніж (інакше ідентичне) завдання відкладеного падіння, створене тимчасовим очищенням таблиці:

Стійка дзвінків, тому що люди їм подобаються

Чи це випадково, чи дизайн - це хтось здогадався. Звичайно, це може змінитися в будь-який час, оскільки цей рівень деталізації виходить за межі підтримуваної поверхні поверхні виробу.

Якщо ви відключите відкладене падіння у всьому світі за допомогою (в основному) недокументованого позначення сліду:

DBCC TRACEON (671, -1);

... у обох випадках угода здійснюється синхронно, і ви не побачите різниці в термінах.

Які будуть відносні наслідки для використання або використання такого оператора усікання? Використовуючи ізоляцію SNAPSHOT, tempdb часто підкреслюється, і я думаю, що звільнення простору, який використовується у tempdb, з великої темп-таблиці як можна швидше запобіжить непотрібне зростання tempdb. Чи може ця потенційна економія простору ціною продуктивності?

Я серйозно сумніваюся, що це коли-небудь змінить будь-який спосіб. Якщо tempdb розміщений відповідно до пікових потреб вашого робочого навантаження, то відкладене падіння відбудеться через одну секунду чи три не має значення. Робиться та ж робота; це лише невелика різниця в термінах.

З іншого боку: Якщо вам зручніше користуватися TRUNCATE TABLEтимчасовими таблицями наприкінці збережених процедур, перейдіть до цього. Я не знаю про якийсь конкретний мінус цього робити.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.