TempDB 系統資料庫是全域資源,適用於所有連線到 SQL Server 執行個體或 SQL Database 的使用者。 Tempdb 用以保留:
明確建立的暫存「使用者物件」 (例如:全域或本機暫存資料表與索引、暫存預存程序、資料表變數、資料表值函式中傳回的資料表,或資料指標)。
資料庫引擎建立的內部物件。 其中包括:
注意
每個內部物件至少使用 9 頁、一個 IAM 頁面和一個八頁的範圍。 如需分頁與範圍的詳細資訊,請參閱分頁與範圍。
重要
Azure SQL Database 單一資料庫和彈性集區支援儲存在 TempDB 中,只限於資料庫層級的全域暫存資料表和全域暫存預存程序。 在同一 Azure SQL 資料庫中的所有使用者工作階段,會共用全域暫存資料表和全域暫存預存程序。 其他 Azure SQL 資料庫的使用者工作階段無法存取全域暫存資料表。 如需詳細資訊,請參閱限定資料庫範圍的全域暫存資料表 (Azure SQL Database)。 Azure SQL Database 受控執行個體 與 SQL Server 支援相同的暫存物件。 針對 Azure SQL Database 單一資料庫和彈性集區,只會套用 master 資料庫和 TempDB 資料庫。 如需詳細資訊,請參閱什麼是 Azure SQL Database 伺服器。 如需 Azure SQL Database 單一資料庫和彈性集區內容中 TempDB 的討論,請參閱 Azure SQL Database 單一資料庫和彈性集區中的 TempDB 資料庫。 針對 Azure SQL Database 受控執行個體,則會套用所有系統資料庫。
「版本存放區」 是保存資料列的資料頁集合;這些資料列是支援使用資料列版本設定功能的必要項目。 版本存放區有兩個:一個是一般版本存放區,一個是線上索引建立版本存放區。 版本存放區包含:
至少會記錄 TempDB 內的作業,以便回復交易。 每次啟動時都會重新建立 TempDB SQL Server ,這樣系統永遠會以乾淨的資料庫複本啟動。 連接中斷時會自動卸除暫存資料表與預存程序,且系統關閉時所有連接都會停止。 因此, TempDB 中的任何資料都不會從 SQL Server 的一個工作階段儲存到其他的工作階段。 TempDB不允許進行備份和還原作業。
下表列出 SQL Server 中的 TempDB 資料和記錄檔的初始設定值,其是以 Model 資料庫的預設值為依據。 對於不同版本的 SQL Server,這些檔案的大小稍有不同。
檔案 | 邏輯名稱 | 實體名稱 | 初始大小 | 檔案成長 |
---|---|---|---|---|
主要資料 | tempdev | tempdb.mdf | 8 MB | 自動成長 64 KB,直到磁碟滿了為止 |
次要資料檔* | temp# | tempdb_mssql_#.ndf | 8 MB | 自動成長 64 KB,直到磁碟滿了為止 |
Log | templog | templog.ldf | 8 MB | 自動成長 64 MB,最大至 2 TB。 |
* 檔案數目取決於電腦上 (邏輯) 處理器的數量。 一般而言,如果邏輯處理器的數目小於或等於 8,請使用與邏輯處理器數目相同的資料檔案數目。 如果邏輯處理器的數目大於 8,請使用 8 個資料檔案,要是競爭的情況仍持續發生,請以 4 的倍數增加資料檔案數目,直到競爭縮減到可接受的程度;或是對工作負載/程式碼進行變更。
注意
資料檔案數目預設值取決於 KB 2154845內的一般指導方針。
若要移動 TempDB 資料和記錄檔,請參閱 移動系統資料庫。
下表列出 TempDB 資料庫中每個資料庫選項的預設值,以及這些選項是否可以修改。 若要檢視這些選項目前的設定,請參閱 sys.databases 目錄檢視。
資料庫選項 | 預設值 | 可以修改 |
---|---|---|
ALLOW_SNAPSHOT_ISOLATION | OFF | 是 |
ANSI_NULL_DEFAULT | OFF | 是 |
ANSI_NULLS | OFF | 是 |
ANSI_PADDING | OFF | 是 |
ANSI_WARNINGS | OFF | 是 |
ARITHABORT | OFF | 是 |
AUTO_CLOSE | OFF | 否 |
AUTO_CREATE_STATISTICS | 開啟 | 是 |
AUTO_SHRINK | OFF | 否 |
AUTO_UPDATE_STATISTICS | 開啟 | 是 |
AUTO_UPDATE_STATISTICS_ASYNC | OFF | 是 |
CHANGE_TRACKING | OFF | 否 |
CONCAT_NULL_YIELDS_NULL | OFF | 是 |
CURSOR_CLOSE_ON_COMMIT | OFF | 是 |
CURSOR_DEFAULT | GLOBAL | 是 |
資料庫可用性選項 | ONLINE MULTI_USER READ_WRITE |
否 否 否 |
DATE_CORRELATION_OPTIMIZATION | OFF | 是 |
DB_CHAINING | 開啟 | 否 |
ENCRYPTION | OFF | 否 |
MIXED_PAGE_ALLOCATION | OFF | 否 |
NUMERIC_ROUNDABORT | OFF | 是 |
PAGE_VERIFY | CHECKSUM (新安裝的 SQL Server)。 NONE (升級的 SQL Server)。 |
是 |
PARAMETERIZATION | 簡單 | 是 |
QUOTED_IDENTIFIER | OFF | 是 |
READ_COMMITTED_SNAPSHOT | OFF | 否 |
RECOVERY | 簡單 | 否 |
RECURSIVE_TRIGGERS | OFF | 是 |
Service Broker 選項 | ENABLE_BROKER | 是 |
TRUSTWORTHY | OFF | 否 |
如需這些資料庫選項的描述,請參閱 ALTER DATABASE SET 選項 (Transact-SQL)。
SLO | TempDB 資料檔案大小上限 (GB) | TempDB 資料檔案數 | TempDB 資料檔案大小上限 (GB) |
---|---|---|---|
基本 | 13 | 1 | 13 |
S0 | 13 | 1 | 13 |
S1 | 13 | 1 | 13 |
S2 | 13 | 1 | 13 |
S3 | 32 | 1 | 32 |
S4 | 32 | 2 | 64 |
S6 | 32 | 3 | 96 |
S7 | 32 | 6 | 192 |
S9 | 32 | 12 | 384 |
S12 | 32 | 12 | 384 |
P1 | 13 | 12 | 156 |
P2 | 13 | 12 | 156 |
P4 | 13 | 12 | 156 |
P6 | 13 | 12 | 156 |
P11 | 13 | 12 | 156 |
P15 | 13 | 12 | 156 |
Premium 彈性集區 (所有 DTU 設定) | 13 | 12 | 156 |
標準彈性集區 (S0-S2) | 13 | 12 | 156 |
標準彈性集區 (S3 以上) | 32 | 12 | 384 |
基本彈性集區 (所有 DTU 設定) | 13 | 12 | 156 |
請參閱以 vCore 為基礎的資源限制
下列作業不能在 TempDB 資料庫上執行:
任何使用者都可以在 TempDB 中建立暫時物件。 除非收到其他權限,否則使用者只能存取自己的物件。 您可以撤銷 TempDB 的連線權限來阻止使用者使用 TempDB,不過不建議您這樣做,因為有些常式作業需要使用 TempDB。
TempDB 資料庫的大小和實體位置會影響系統效能。 例如,如果為 TempDB 定義的大小太小,每次您重新啟動 SQL Server 的執行個體時,部分系統處理負載可能會開始將 TempDB 自動成長到支援工作負載所需的大小。
可能的話,請使用資料庫檔案立即初始化來改善資料檔案成長作業的效能。
您可將檔案大小設定為夠大的值來容納環境中的典型工作負載,藉此為所有 TempDB 檔案預先配置空間。 預先配置可防止 TempDB 擴充過於頻繁而影響效能。 TempDB 資料庫應該設為自動成長,但這應該用來增加非計劃中例外狀況的磁碟空間。
由於 使用的比例填入演算法較偏好可用空間多的檔案配置,因此每個檔案群組SQL Server內的資料檔應該大小相同。 將 TempDB 分割成相同大小的多個資料檔案時,可讓使用 TempDB 的作業具有較高的平行效率。
將檔案成長增量設成合理的大小,可避免 TempDB 資料庫檔案每次成長量的值太小。 如果檔案的成長比寫入 TempDB 的資料量少太多,那麼 TempDB 可能必須經常擴大並影響效能。
若要檢查目前的 TempDB 大小和成長參數,請使用下列查詢:
SQL複製
SELECT name AS FileName,
size*1.0/128 AS FileSizeInMB,
CASE max_size
WHEN 0 THEN 'Autogrowth is off.'
WHEN -1 THEN 'Autogrowth is on.'
ELSE 'Log file grows to a maximum size of 2 TB.'
END,
growth AS 'GrowthValue',
'GrowthIncrement' =
CASE
WHEN growth = 0 THEN 'Size is fixed.'
WHEN growth > 0 AND is_percent_growth = 0
THEN 'Growth value is in 8-KB pages.'
ELSE 'Growth value is a percentage.'
END
FROM tempdb.sys.database_files;
GO
將 TempDB 資料庫放在快速的 I/O 子系統上。 如果有許多直接連接的磁碟,請使用磁碟條狀配置。 除非您發生 I/O 瓶頸,否則一或多個 TempDB 資料檔案不一定要在不同的磁碟或主軸上。
將 TempDB 資料庫放在不同於使用者資料庫所使用的磁碟上。
從 SQL Server 2016 (13.x) 開始,TempDB 效能已針對下列各方面進一步最佳化:
/SQLTEMPDBFILECOUNT
完成此工作。 根據預設,安裝程式會新增與邏輯處理器計數一樣多的 TempDB 資料檔案 (或是 8 個),以較低者為準。如需 TempDB 中效能改進的詳細資訊,請參閱下列部落格文章:
TEMPDB - 檔案與追蹤旗標及更新,太棒了!
TempDB 中繼資料競爭一直以來都是在 SQL Server 上執行之許多工作負載的延展性瓶頸。 SQL Server 2019 (15.x) 引進的新功能是記憶體內部資料庫功能系列的一部分,記憶體最佳化的 TempDB 中繼資料能有效移除此瓶頸,並解除鎖定大量 TempDB 工作負載的新層級延展性。 在 SQL Server 2019 (15.x) 中,涉及管理暫存資料表中繼資料的系統資料表,可以移至不需閂鎖之非持久性經記憶體最佳化的資料表。
請使用下列指令碼,選擇加入這項新功能:
SQL複製
ALTER SERVER CONFIGURATION SET MEMORY_OPTIMIZED TEMPDB_METADATA = ON
這項設定變更需要重新啟動服務才會生效。
此實作有些限制請務必注意:
功能開關切換不是動態的。 因為內部變更需要作用於 TempDB 的結構,所以啟用或停用此功能都必須重新開機。
單筆交易不一定會存取多個資料庫中經記憶體最佳化的資料表。 這表示任何牽涉到使用者資料庫中經記憶體最佳化之資料表的交易,都不能存取相同交易中的 TempDB 系統檢視表。 如果您嘗試存取和使用者資料庫中經記憶體最佳化的資料表同一交易中的 TempDB 系統檢視表,您會收到下列錯誤:
複製
A user transaction that accesses memory optimized tables or natively compiled modules cannot access more than one user database or databases model and msdb, and it cannot write to master.
範例:
SQL複製
BEGIN TRAN
SELECT *
FROM tempdb.sys.tables -----> Creates a user In-Memory OLTP Transaction on Tempdb
INSERT INTO ..
VALUES (1) ----> Attempts to create user In-Memory OLTP transaction but will fail
COMMIT TRAN
針對經記憶體最佳化之資料表的查詢不支援鎖定和隔離提示,因此針對經記憶體最佳化之 TempDB 目錄檢視的查詢不支援鎖定和隔離提示。 至於 SQL Server 中的其他系統目錄檢視,針對系統檢視表的所有交易都會是 READ COMMITTED 隔離 (或在本例中為 READ COMMITTED SNAPSHOT)。
啟用經記憶體最佳化的 TempDB 中繼資料時,無法在暫存資料表上建立資料行存放區索引。
由於資料行存放區索引的限制,在啟用記憶體最佳化 TempDB 中繼資料的情況下不支援使用 sp_estimate_data_compression_savings 系統預存程式搭配 COLUMNSTORE 或 COLUMNSTORE_ARCHIVE 資料壓縮參數。
注意
這些限制僅適用於參考 TempDB 系統檢視表時,如有需要,您可在存取使用者資料庫中經記憶體最佳化的資料表時,在相同的交易中建立暫存資料表。
您可以使用下列 T-SQL 命令驗證 TempDB 是否經記憶體最佳化:
複製
SELECT SERVERPROPERTY('IsTempdbMetadataMemoryOptimized')
若伺服器在啟用經記憶體最佳化的 TempDB 中繼資料後因為任何原因而無法啟動,您可以使用 -f 啟動選項,以最小組態啟動 SQL Server 來略過功能。 這可以讓您停用功能,然後以一般模式重新啟動 SQL Server。
在決定 SQL Server生產環境中的 TempDB 適當大小時,您需要考量許多因素。 如本文先前所述,這些因素包括現有的工作負載和使用的 SQL Server 功能。 我們建議您在 SQL Server 測試環境中執行下列工作來分析現有的工作負載:
一旦 TempDB 的磁碟空間用完,會造成 SQL Server 生產環境嚴重中斷,並使執行中的應用程式無法完成作業。 您可以使用 sys.dm_db_file_space_usage 動態管理檢視來監視 TempDB 檔案中所使用的磁碟空間:
SQL複製
-- Determining the Amount of Free Space in TempDB
SELECT SUM(unallocated_extent_page_count) AS [free pages],
(SUM(unallocated_extent_page_count)*1.0/128) AS [free space in MB]
FROM sys.dm_db_file_space_usage;
-- Determining the Amount Space Used by the Version Store
SELECT SUM(version_store_reserved_page_count) AS [version store pages used],
(SUM(version_store_reserved_page_count)*1.0/128) AS [version store space in MB]
FROM sys.dm_db_file_space_usage;
-- Determining the Amount of Space Used by Internal Objects
SELECT SUM(internal_object_reserved_page_count) AS [internal object pages used],
(SUM(internal_object_reserved_page_count)*1.0/128) AS [internal object space in MB]
FROM sys.dm_db_file_space_usage;
-- Determining the Amount of Space Used by User Objects
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]
FROM sys.dm_db_file_space_usage;
此外,若要在工作階段或工作層級監視 TempDB 中的頁面配置或取消配置活動,您可以使用 sys.dm_db_session_space_usage 和 sys.dm_db_task_space_usage 動態管理檢視。 這些檢視可用來識別大量佔用 TempDB 磁碟空間的大型查詢、暫存資料表或資料表變數。 您還可以使用若干計數器來監視 TempDB 可用的空間以及有哪些資源正在使用 tempdb。 如需詳細資訊,請參閱下一節。
SQL複製
-- Obtaining the space consumed by internal objects in all currently running tasks in each session
SELECT session_id,
SUM(internal_objects_alloc_page_count) AS task_internal_objects_alloc_page_count,
SUM(internal_objects_dealloc_page_count) AS task_internal_objects_dealloc_page_count
FROM sys.dm_db_task_space_usage
GROUP BY session_id;
-- Obtaining the space consumed by internal objects in the current session for both running and completed tasks
SELECT R2.session_id,
R1.internal_objects_alloc_page_count
+ SUM(R2.internal_objects_alloc_page_count) AS session_internal_objects_alloc_page_count,
R1.internal_objects_dealloc_page_count
+ SUM(R2.internal_objects_dealloc_page_count) AS session_internal_objects_dealloc_page_count
FROM sys.dm_db_session_space_usage AS R1
INNER JOIN sys.dm_db_task_space_usage AS R2 ON R1.session_id = R2.session_id
GROUP BY R2.session_id, R1.internal_objects_alloc_page_count,
R1.internal_objects_dealloc_page_count;;