揭祕Sql2014新特性-tempdb性能提升
一直以來,在高負載,複雜的生產環境中,tempdb的壓力是成爲整個實例瓶頸的重要因素之一.微軟的工程師們也在各個版本中不斷優化它的使用.到了Sql Server2014又有了新的特性使其性能得tempdb的性能有一定提升.這裏我將通過實例給大家介紹tempdb在新版本中的實現變化.
我們都知道tempdb的日誌無需提前落盤是其快的重要原因之一,日誌無需落盤,那麼數據又是如何操作的呢?這裏先介紹一個重要的概念:主動寫(Eager write)
主動寫: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)用以捕捉主動寫行爲.
我們先來看下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 write
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-2
通過實例我們可以看到在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還是一直在進步.雖說很多不如意,但這裏我爲微軟點個贊.