| 特性 | 表變數 (@table) | 暫存表 (#temp) |
|---|---|---|
| 儲存位置 | 記憶體(資料量大時溢寫 tempdb) | tempdb(磁碟) |
| 作用域 | 批次/預存程序/函數結束自動清除 | 工作階段結束或手動 DROP 清除 |
| 交易與鎖定 | 僅在更新期間持有鎖,不受外部交易回滾影響 | 完整支援交易、回滾、鎖升級 |
| 統計資料 | 無統計資料,優化器假設 1 列 | 有統計資料,支援重新編譯與最佳化 |
| 索引/約束 | 僅支援 PRIMARY KEY、UNIQUE(隱含索引) | 支援所有索引、外鍵、檢查約束 |
| 動態 SQL 可見性 | 不可在 EXEC/sp_executesql 內部存取外部表變數 | 全域暫存表 (##temp) 可跨工作階段存取 |
| 參數傳遞 | 可作為 TABLE 型參數傳入預存程序(SQL 2008+) | 不可作為參數傳遞 |
##temp。-- 表變數範例
DECLARE @t TABLE (id INT PRIMARY KEY, val VARCHAR(20));
INSERT INTO @t SELECT id, name FROM dbo.BigTable WHERE id < 100;
-- 暫存表範例(預先建立索引)
CREATE TABLE #t (id INT PRIMARY KEY, val VARCHAR(20));
CREATE INDEX IX_#t_val ON #t(val);
INSERT INTO #t SELECT id, name FROM dbo.BigTable WHERE id < 1000000;
理解兩者在儲存、統計、鎖定、作用域上的本質差異,依據資料量、查詢複雜度、併發需求靈活選擇,才能發揮最佳效能。