表變數(@table)常被認為「只在記憶體」,實測證實會寫入 tempdb、產生 IO、佔用 Buffer Pool,且在批次結束時釋放。本文提供完整測試腳本與結果分析。
USE tempdb; SET NOCOUNT ON;
EXEC sp_spaceused; -- 插入前
DECLARE @tmp_orders TABLE (list_no INT, id INT);
INSERT INTO @tmp_orders (list_no, id)
SELECT ROW_NUMBER() OVER (ORDER BY Id), Id FROM Test.dbo.Orders;
SELECT TOP 1 name, object_id, type, create_date
FROM sys.objects WHERE type='U' ORDER BY create_date DESC;
EXEC sp_spaceused; -- 插入後(批次未結束)
GO
EXEC sp_spaceused; -- GO 後(批次結束)
sys.objects 可見表變數物件(名稱如 #A1B2C3)GO)後:空間**釋放歸零**SELECT db_name(database_id) AS db, *
FROM sys.dm_io_virtual_file_stats(DB_ID('tempdb'), NULL);
-- 查詢 tempdb 物件在 Buffer Pool 的緩存頁數
SELECT COUNT(*) AS cached_pages, name, index_id
FROM sys.dm_os_buffer_descriptors bd
JOIN (
SELECT object_name(object_id) AS name, index_id, allocation_unit_id
FROM sys.allocation_units au
JOIN sys.partitions p ON au.container_id = p.hobt_id
WHERE au.type IN (1,3)
UNION ALL
SELECT object_name(object_id), index_id, allocation_unit_id
FROM sys.allocation_units au
JOIN sys.partitions p ON au.container_id = p.partition_id
WHERE au.type = 2
) obj ON bd.allocation_unit_id = obj.allocation_unit_id
WHERE database_id = DB_ID()
GROUP BY name, index_id
ORDER BY cached_pages DESC;
| 指標 | 表變數行為 |
|---|---|
| tempdb 空間 | 佔用(批次期間) |
| 實體 IO | 產生寫入/讀取 |
| Buffer Pool | 佔用緩存頁面 |
| 生命週期 | 批次結束自動釋放 |
| 統計資訊 | 無統計資訊(優化器用固定估算) |
#temp) 更好**