In SQL Server, the tempdb
database is the unsung hero behind countless operations—storing temporary tables, managing sorting and hashing for complex queries, and handling version stores for snapshot isolation. But when tempdb falters, your entire system can grind to a halt. Unexplained slowdowns, sudden space exhaustion, or blocking caused by allocation contention are just a few of the crises that can erupt if tempdb isn’t closely monitored.
This guide is your tactical toolkit for diagnosing and resolving tempdb issues before they escalate into full-blown outages. You’ll learn how to:
USE tempdb;
GO
SELECT
name AS [File Name],
physical_name AS [Physical Path],
size/128.0 AS [Current Size (MB)], -- Converts 8KB pages to MB
size/128.0 - CAST(FILEPROPERTY(name, 'SpaceUsed') AS int)/128.0 AS [Free Space (MB)],
growth AS [Growth (MB or %)] -- Growth setting (MB or percentage)
FROM sys.database_files;
What This Does:
tempdb
, showing their current size, free space, and auto-growth settings.tempdb
is close to capacity, which can trigger auto-growth events (a performance killer).SELECT
SUM(user_object_reserved_page_count)*8/1024 AS [User Objects (MB)], -- Temp tables, table variables
SUM(internal_object_reserved_page_count)*8/1024 AS [Internal Objects (MB)], -- Sorts, hashes, spools
SUM(version_store_reserved_page_count)*8/1024 AS [Version Store (MB)], -- Snapshot isolation versions
SUM(unallocated_extent_page_count)*8/1024 AS [Free Space (MB)] -- Unused space
FROM sys.dm_db_file_space_usage;
What This Does:
tempdb
space usage into user objects (e.g., temp tables), internal objects (query execution artifacts), and version store (snapshot isolation).ORDER BY
) or grouping (GROUP BY
).DECLARE @current_trace NVARCHAR(500);
SELECT @current_trace = path
FROM sys.traces
WHERE is_default = 1;
SELECT
tg.DatabaseName,
tg.StartTime,
tg.FileName,
tg.Duration/1000 AS [Duration (ms)], -- Time taken for auto-growth
tg.ApplicationName,
tg.LoginName,
(tg.IntegerData * 8)/1024 AS [Growth (MB)] -- Pages grown converted to MB
FROM sys.fn_trace_gettable(@current_trace, DEFAULT) tg
WHERE
(tg.EventClass = 92 OR tg.EventClass = 93) -- 92: Data file grow, 93: Log file grow
AND tg.DatabaseName = 'tempdb'
AND tg.StartTime >= DATEADD(HOUR, -24, GETDATE())
ORDER BY tg.StartTime DESC;
What This Does:
tempdb
auto-growth events from the default trace over the last 24 hours.tempdb
files, leading to file fragmentation and I/O latency.LoginName
or ApplicationName
to pinpoint responsible workloads.SELECT
es.session_id,
es.login_name,
es.program_name,
es.host_name,
(tsu.user_objects_alloc_page_count * 8)/1024 AS [User Objects (MB)],
(tsu.internal_objects_alloc_page_count * 8)/1024 AS [Internal Objects (MB)]
FROM sys.dm_db_session_space_usage tsu
INNER JOIN sys.dm_exec_sessions es
ON tsu.session_id = es.session_id
ORDER BY [User Objects (MB)] + [Internal Objects (MB)] DESC;
What This Does:
tempdb
usage in MB.SELECT
er.session_id,
es.login_name,
er.start_time,
er.status,
er.command,
(tsu.user_objects_alloc_page_count * 8)/1024 AS [User Objects (MB)],
(tsu.internal_objects_alloc_page_count * 8)/1024 AS [Internal Objects (MB)],
qt.text AS [Query Text]
FROM sys.dm_db_task_space_usage tsu
INNER JOIN sys.dm_exec_requests er
ON tsu.session_id = er.session_id
INNER JOIN sys.dm_exec_sessions es
ON tsu.session_id = es.session_id
OUTER APPLY sys.dm_exec_sql_text(er.sql_handle) qt
ORDER BY [User Objects (MB)] + [Internal Objects (MB)] DESC;
What This Does:
tempdb
consumption.tempdb
usage to specific SQL statements (e.g., sorts, hashes, temp tables).ORDER BY
on a large dataset may consume internal objects.SELECT
t.name AS [Object Name],
t.type_desc AS [Object Type],
(au.total_pages * 8)/1024 AS [Size (MB)],
au.type_desc AS [Allocation Type]
FROM tempdb.sys.allocation_units au
INNER JOIN tempdb.sys.partitions p
ON au.container_id = p.hobt_id
INNER JOIN tempdb.sys.tables t
ON p.object_id = t.object_id
WHERE au.type_desc IN ('IN_ROW_DATA', 'LOB_DATA', 'ROW_OVERFLOW_DATA');
What This Does:
tempdb
.#temp
tables not dropped after use).LOB_DATA
or ROW_OVERFLOW_DATA
allocations indicate large object storage.SELECT
(version_store_reserved_page_count * 8)/1024 AS [Version Store (MB)]
FROM sys.dm_db_file_space_usage
WHERE database_id = DB_ID('tempdb');
What This Does:
READ_COMMITTED_SNAPSHOT
or SNAPSHOT ISOLATION
can bloat the version store.
Issue |
Diagnosis |
Solution |
---|---|---|
Excessive Internal Objects |
High |
Optimize queries with |
Version Store Growth |
High |
Kill long-running transactions. |
User Objects Not Freed |
Persistent |
Ensure temp tables are dropped post-use. |
Frequent Auto-Growth |
Repeated events in default trace. |
Pre-size |
SELECT INTO
: Use explicit schemas for temp tables to minimize logging.sys.query_store_runtime_stats
to track tempdb-heavy queries.By systematically analyzing tempdb
usage with these queries, you can preemptively address space issues, optimize query performance, and ensure smooth SQL Server operations. Regularly monitor key DMVs and automate alerts for tempdb
growth to stay ahead of problems.