一直以來,在高負載,複雜的生產環境中,tempdb的壓力是成爲整個實例瓶頸的重要因素之一.微軟的工程師們也在各個版本中不斷優化它的使用.到了Sql Server2014又有了新的特性使其性能得tempdb的性能有必定提高.這裏我將經過實例給你們介紹tempdb在新版本中的實現變化.html
咱們都知道tempdb的日誌無需提早落盤是其快的重要緣由之一,日誌無需落盤,那麼數據又是如何操做的呢?這裏先介紹一個重要的概念:主動寫(Eager write)sql
主動寫:Sql server引擎在面對最小化日誌操做的情形時(blukinsert,select into,etc)會採用主動寫的方式將數據頁批量刷入(通常32頁/次)磁盤,以減少惰性寫(lazy write),檢查點(checkpoint)操做時所帶來的磁盤壓力.數據庫
熟悉Sqlserver開發的DBA或是開發人員應該知道,在使用tempdb時存在着大量的最小化日誌操做,如select * into #xx,而Sql Server因爲其引擎主動寫的特性使得即使是批量寫入的優化方式也會使得因爲tempdb的頻繁寫入使整個磁盤IO面臨較大的壓力.好在微軟的工程師們注意到了這個狀況,在Sql2014的tempdb中引擎放鬆了主動寫在tempdb的必要性,在特定操做中數據頁能夠駐留在內存中而無需主動刷入磁盤(Sqlserver認爲短暫的時間窗口),減輕了磁盤的負載,於此同時也使得tempdb的性能更高效.這裏我經過一個簡單的實例給你們演示.服務器
注:爲了演示不一樣版本的特性,咱們須要開啓跟蹤標記(TF 3917)用以捕捉主動寫行爲.ide
咱們先來看下sql2008R2 SP2下的狀況 如圖1-1性能
select @@VERSION--Microsoft SQL Server 2008 R2 (SP2) - 10.50.4000.0 dbcc traceON(3604,3917,-1)----catch eager write select * into aaa from dbo.bigProduct dbcc traceOFF(3604,3917,-1)-----remember turn off the TF!
圖1-1測試
接下來一樣的腳本咱們在sql2014中執行如圖1-2優化
Code Sql2014 tempdb does no eager writespa
select @@VERSION--Microsoft SQL Server 2014 - 12.0.2000.8 (X64) dbcc traceON(3604,3917,-1)----catch eager write select * into #ttt from dbo.bigProduct dbcc traceOFF(3604,3917,-1)-----remember turn off the TF!
圖1-23d
經過實例咱們能夠看到在sql2014中,tempdb中的操做並無由於select into而觸發主動寫,使得磁盤寫操做得以免.
注:此特性只實用與tempdb中,用戶數據庫新版本中依舊有主動寫實現特性.感興趣的朋友能夠自行測試
也許有的朋友認爲批量寫入已是優化行爲,這個tempdb中的小小變更不足緩解其瓶頸問題,這裏咱們經過一個簡單的實例來講明下.
Sql2008R2 SP2 code
注:測試前請重啓下sql server實例,使得tempdb計數儘可能準確
測試結果如圖 1-3
use AdventureWorks go create proc p_tempdbtest as select * into #ttt from dbo.bigProduct declare @t datetime2=sysutcdatetime() declare @i int set @i=1 while (@i<100) begin exec p_tempdbtest select @i=@i+1 end select [extime]=DATEDIFF(S,@t,sysutcdatetime()) SELECT d.name AS database_name, f.name AS [file_name], f.physical_name, f.type_desc, vf.num_of_reads, vf.num_of_writes FROM sys.dm_io_virtual_file_stats(NULL, NULL) AS vf INNER JOIN sys.databases AS d ON d.database_id = vf.database_id INNER JOIN sys.master_files AS f ON f.file_id = vf.file_id AND f.database_id = vf.database_id where f.database_id = db_id('tempdb')
圖1-3
Sq2014 code 執行Sql2008R2 SP2中腳本
注:測試前請重啓下sql server實例,使得tempdb計數儘可能準確
測試結果如圖 1-4
圖1-4
因爲筆者的測試的兩臺服務器測試機均爲4塊R5 15K磁盤,能夠認爲測試過程磁盤IO環境相同.經過測試咱們能夠看到,新版本中的tempdb的這個規避必定主動寫的行爲可使得tempdb不少情形中(select into,create index,etc)寫的壓力獲得極大緩解,提升的單個操做效率的同時也使得總體性能提高.
注:Sql Server的CSS團隊聲稱在sql 2012版本的後續補丁中可能實現此功能.
Sql Server在面對很大內存壓力時,惰性寫(Lazy Write)一樣會將數據頁刷入磁盤.、
Tempdb中非臨時對象仍然需主動寫.(感興趣朋友能夠自行測試)
結語:關係型數據庫發展至今,我的認爲理念上很難再有大的突破,產品的細節實現更能決體現產品的優秀程度.微軟在根據使用的場景對特定庫的不一樣操做依據其特色採用不一樣的實現方式讓我以爲SqlServer仍是一直在進步.雖然說不少不如意,但這裏我爲微軟點個贊.