DATEADD和DATEDIFF比轉(zhuǎn)換為varchar更好。這兩個查詢都有相同的執(zhí)行計劃,但是執(zhí)行計劃主要是關(guān)于數(shù)據(jù)訪問策略,并且不總是顯示執(zhí)行所有部分所需的CPU時間所涉及的隱含成本。如果兩個查詢都針對數(shù)百萬行的表運行,則使用DateDiff的CPU時間可以接近轉(zhuǎn)換CPU時間的三分之一!
要查看查詢的執(zhí)行計劃:
set showplan_text onGO
DATEADD和DATEDIFF都將執(zhí)行轉(zhuǎn)換_隱式。
雖然對某些人來說,轉(zhuǎn)換解決方案更簡單、更容易閱讀,但它是慢點。不需要將數(shù)據(jù)轉(zhuǎn)換為DateTime(這是服務(wù)器隱式完成的)。之后,DateDiff方法對于DateAdd也沒有真正的需求,因為整數(shù)結(jié)果也將被隱式轉(zhuǎn)換回datetime。
從數(shù)據(jù)表中選擇轉(zhuǎn)換(varchar,MyDate,101)
|--Compute Scalar(DEFINE:([Expr1004]=CONVERT(varchar(30),[TEST].[dbo].[DatesTable].[MyDate],101)))
|--Table Scan(OBJECT:([TEST].[dbo].[DatesTable]))
從數(shù)據(jù)表中選擇DATEADD(dd,0,DATEDIFF(dd,0,MyDate)
|--Compute Scalar(DEFINE:([Expr1004]=dateadd(day,(0),CONVERT_IMPLICIT(datetime,datediff(day,'1900-01-01 00:00:00.000',CONVERT_IMPLICIT
(datetime,[TEST].[dbo].[DatesTable].[MyDate],0)),0))))
|--Table Scan(OBJECT:([TEST].[dbo].[DatesTable]))
正如@digi所建議的那樣,使用place()具有更接近DateDiff的性能,但不建議將Datetime數(shù)據(jù)類型轉(zhuǎn)換為浮動和返回,但并不總是產(chǎn)生原始值。
記住伙計們:不要相信任何人。查看性能統(tǒng)計數(shù)據(jù),并自己測試它!
在測試結(jié)果時要小心。選擇多個行將隱藏性能差異,因為通過網(wǎng)絡(luò)發(fā)送行要比執(zhí)行計算所用的時間要長。因此,請確保所有行的工作都由服務(wù)器完成,但沒有發(fā)送到客戶端的行集。
對于某些人來說,緩存優(yōu)化何時影響查詢似乎有些混亂。在同一批或在不同批處理中運行兩個查詢對緩存沒有影響。因此,您可以手動終止緩存,也可以簡單地多次來回運行查詢。對查詢#2的任何優(yōu)化也會影響后續(xù)的查詢,因此如果您愿意,可以拋出執(zhí)行#1。
這是完整測試腳本和性能結(jié)果這證明DateDiff比轉(zhuǎn)換為varchar要快得多。