Sql-Server

選擇臨時表通常比選擇實際表更快嗎?

  • May 18, 2020

我以為我曾經在某處讀到過,寫入 tempdb 比不在 tempdb 中的實際表要快。這是真的嗎?我想我記得它說了一些關於 tempdb 並將數據儲存在記憶體中的特別之處?

寫入 tempdb 比不在 tempdb 中的實際表快

這是真的。TempDb 中有兩個 IO 增強功能。

對使用者數據庫中的表的寫入必須在送出時將其日誌記錄刷新到磁碟,或者如果是最低限度記錄的插入(如 SELECT … INTO),則必須在送出時將數據庫頁面刷新到磁碟。最小日誌記錄在使用者數據庫中的工作方式是將數據庫頁面直接寫入磁碟。到 SELECT … INTO 完成時,新頁面已全部寫入物理文件。

TempDb 寫入不必在送出時刷新到磁碟,因為 TempDb 在失敗後永遠不會恢復。所以他們根本不是。您的更改會生成日誌記錄,但日誌緩衝區僅在其已滿時才會刷新到磁碟,而不是每次送出。

自 SQL Server 2014 起,TempDb 中的最低限度記錄插入也不總是寫入磁碟。如果您載入一個小的、短暫的臨時表,它可能永遠不會被寫入磁碟。該日誌將包含一些關於表的頁面分配和元數據條目的記錄,僅此而已。

EG 在 tempdb、完整恢復數據庫和簡單恢復數據庫中執行以下批處理以查看差異。

drop table if exists foo
go
declare @data bigint
declare @log bigint 
select @log = sum(case when type_desc = 'LOG' then num_of_bytes_written end) 
     ,@data =  sum(case when type_desc = 'ROWS' then num_of_bytes_written end) 
from sys.database_files f
cross apply sys.dm_io_virtual_file_stats(db_id(),f.file_id) fs

select * 
into foo
from sys.objects 

select -@log + sum(case when type_desc = 'LOG' then num_of_bytes_written end)  log_bytes
     ,-@data +  sum(case when type_desc = 'ROWS' then num_of_bytes_written end) data_bytes
     , (select recovery_model_desc from sys.databases where database_id = db_id()) recovery_model
from sys.database_files f
cross apply sys.dm_io_virtual_file_stats(db_id(),f.file_id) fs

你會看到類似的東西:

對於簡單的恢復:

log_bytes            data_bytes           recovery_model
-------------------- -------------------- ---------------
24576                16384                SIMPLE

完全恢復:

log_bytes            data_bytes           recovery_model
-------------------- -------------------- ---------------
36864                0                    FULL

對於 tempdb:

log_bytes            data_bytes           recovery_model
-------------------- -------------------- ---------------
0                    0                    SIMPLE

有時對於 tempdb,您會看到日誌緩衝區已刷新:

log_bytes            data_bytes           recovery_model
-------------------- -------------------- ---------------
61440                0                    SIMPLE

引用自:https://dba.stackexchange.com/questions/258014