SQL Server 2008 और ऊपर
SQL Server 2008 और ऊपर में, निश्चित रूप से सबसे तेज़ तरीका है Convert(date, @date)
। यह एक करने के लिए वापस डाली जा सकती है, datetime
या datetime2
यदि आवश्यक हो।
SQL Server 2005 और पुराने में वास्तव में सबसे अच्छा क्या है?
मैंने एसक्यूएल सर्वर में एक तारीख से समय को कम करने के लिए सबसे तेज़ होने के बारे में असंगत दावे देखे हैं, और कुछ लोगों ने यह भी कहा कि उन्होंने परीक्षण किया था, लेकिन मेरा अनुभव अलग रहा है। तो चलिए कुछ और कड़े परीक्षण करते हैं और सभी को स्क्रिप्ट देने देते हैं ताकि अगर मैं कोई गलती करूं तो लोग मुझे सही कर सकें।
फ्लोट संभाषण सटीक नहीं हैं
सबसे पहले, मैं परिवर्तित datetime
करने से दूर रहूंगा float
, क्योंकि यह सही तरीके से परिवर्तित नहीं होता है। हो सकता है कि आप समय निकालने वाली चीज़ को सही तरीके से कर पाएं, लेकिन मुझे लगता है कि इसका उपयोग करना एक बुरा विचार है, क्योंकि यह डेवलपर्स को स्पष्ट रूप से सूचित करता है कि यह एक सुरक्षित संचालन है और यह नहीं है । जरा देखो तो:
declare @d datetime;
set @d = '2010-09-12 00:00:00.003';
select Convert(datetime, Convert(float, @d));
यह कुछ ऐसा नहीं है जो हमें अपने कोड में या अपने उदाहरणों में लोगों को ऑनलाइन सिखाना चाहिए।
इसके अलावा, यह सबसे तेज़ तरीका भी नहीं है!
प्रमाण - प्रदर्शन परीक्षण
यदि आप कुछ परीक्षण स्वयं करना चाहते हैं, तो यह देखने के लिए कि विभिन्न विधियाँ वास्तव में कैसे स्टैक करती हैं, तो आपको टेस्टर को चलाने के लिए इस सेटअप स्क्रिप्ट की आवश्यकता होगी:
create table AllDay (Tm datetime NOT NULL CONSTRAINT PK_AllDay PRIMARY KEY CLUSTERED);
declare @d datetime;
set @d = DateDiff(Day, 0, GetDate());
insert AllDay select @d;
while @@ROWCOUNT != 0
insert AllDay
select * from (
select Tm =
DateAdd(ms, (select Max(DateDiff(ms, @d, Tm)) from AllDay) + 3, Tm)
from AllDay
) X
where Tm < DateAdd(Day, 1, @d);
exec sp_spaceused AllDay;
कृपया ध्यान दें कि यह आपके डेटाबेस में 427.57 एमबी तालिका बनाता है और इसे चलाने के लिए 15-30 मिनट की तरह कुछ लगेगा। यदि आपका डेटाबेस छोटा है और 10% की वृद्धि के लिए सेट है तो आपको पहले बड़े आकार की तुलना में अधिक समय लगेगा।
अब वास्तविक प्रदर्शन परीक्षण स्क्रिप्ट के लिए। कृपया ध्यान दें कि ग्राहक को पंक्तियों को वापस नहीं करना उद्देश्यपूर्ण है क्योंकि यह 26 मिलियन पंक्तियों पर महंगा है और विधियों के बीच प्रदर्शन के अंतर को छिपाएगा।
प्रदर्शन के परिणाम
set statistics time on;
GO
declare
@dd date,
@d datetime,
@di int,
@df float,
@dv varchar(10);
select @d = CONVERT(date, Tm) from AllDay;
select @d = CAST(Tm - 0.50000004 AS int) from AllDay;
select @d = DATEDIFF(DAY, 0, Tm) from AllDay;
select @d = FLOOR(CAST(Tm as float)) from AllDay;
select @d = CONVERT(VARCHAR(8), Tm, 112) from AllDay;
select @d = CONVERT(CHAR(8), Tm, 112) from AllDay;
select @d = CONVERT(VARCHAR(10), Tm, 101) from AllDay;
select @dd = Tm from AllDay;
select @di = CAST(Tm - 0.50000004 AS int) from AllDay;
select @di = DATEDIFF(DAY, 0, Tm) from AllDay;
select @df = FLOOR(CAST(Tm as float)) from AllDay;
select @dv = CONVERT(VARCHAR(8), Tm, 112) from AllDay;
select @dv = CONVERT(CHAR(8), Tm, 112) from AllDay;
select @dv = CONVERT(VARCHAR(10), Tm, 101) from AllDay;
GO
set statistics time off;
कुछ जुआ विश्लेषण
इस बारे में कुछ नोट्स। सबसे पहले, यदि केवल एक ग्रुप बीवाई या तुलना का प्रदर्शन किया जाता है, तो उसे वापस बदलने की कोई आवश्यकता नहीं है datetime
। इसलिए आप कुछ सीपीयू बचा सकते हैं, जब तक कि आपको प्रदर्शन उद्देश्यों के लिए अंतिम मूल्य की आवश्यकता न हो। आप अनकवर्ड वैल्यू के आधार पर भी ग्रुप बना सकते हैं और रूपांतरण को केवल सेलेक्ट क्लॉज में डाल सकते हैं:
select Convert(datetime, DateDiff(dd, 0, Tm))
from (select '2010-09-12 00:00:00.003') X (Tm)
group by DateDiff(dd, 0, Tm)
यह भी देखें कि संख्यात्मक रूपांतरण को वापस बदलने में केवल थोड़ा अधिक समय कैसे लगता है datetime
, लेकिन varchar
रूपांतरण लगभग दोगुना हो जाता है? यह सीपीयू के उस हिस्से को प्रकट करता है जो प्रश्नों में तिथि गणना के लिए समर्पित है। सीपीयू उपयोग के कुछ भाग हैं जिनमें तारीख की गणना शामिल नहीं है, और यह उपरोक्त प्रश्नों में 19875 एमएस के करीब कुछ प्रतीत होता है। तब रूपांतरण कुछ अतिरिक्त राशि लेता है, इसलिए यदि दो रूपांतरण हैं, तो उस राशि का उपयोग लगभग दो बार किया जाता है।
अधिक परीक्षा से पता चलता है कि तुलना में Convert(, 112)
, Convert(, 101)
क्वेरी में कुछ अतिरिक्त सीपीयू व्यय होता है (क्योंकि यह लंबे समय तक उपयोग करता है varchar
?), क्योंकि दूसरा रूपांतरण वापस date
प्रारंभिक रूपांतरण में उतना खर्च नहीं करता है varchar
, लेकिन इसके साथ Convert(, 112)
यह 20000 के करीब है। एमएस सीपीयू आधार लागत।
यहाँ सीपीयू समय पर उन गणनाओं को बताया गया है जो मैंने उपरोक्त विश्लेषण के लिए उपयोग की हैं:
method round single base
date 21324 19891 18458
int 23031 21453 19875
datediff 23782 23218 22654
float 36891 29312 21733
varchar-112 102984 64016 25048
varchar-101 123375 65609 7843
दौर एक दौर यात्रा के लिए सीपीयू समय है datetime
।
एकल , वैकल्पिक डेटा प्रकार के लिए एक रूपांतरण के लिए सीपीयू समय है (वह जो समय भाग को हटाने का दुष्प्रभाव है)।
आधारsingle
दो इनवोकेशन के बीच के अंतर से घटाव की गणना है single - (round - single)
:। यह एक बॉलपार्क आंकड़ा है जो उस डेटा प्रकार से और उसके लिए रूपांतरण को मानता है और datetime
दोनों दिशाओं में लगभग समान है। ऐसा प्रतीत होता है कि यह धारणा सही नहीं है, लेकिन करीब है क्योंकि मूल्य केवल एक अपवाद के साथ 20000 एमएस के करीब हैं।
एक और दिलचस्प बात यह है कि आधार लागत लगभग एकल Convert(date)
विधि के बराबर है (जिसमें लगभग 0 लागत होनी चाहिए, क्योंकि सर्वर आंतरिक रूप से पूर्णांक दिन भाग को datetime
डेटा प्रकार के पहले चार बाइट्स से बाहर निकाल सकता है )।
निष्कर्ष
तो यह कैसा दिखता है, एकल-दिशा varchar
रूपांतरण विधि में लगभग 1.8 μs और एकल-दिशा DateDiff
विधि में लगभग 0.18 μs लगते हैं। मैं 254520,000 पंक्तियों के लिए 18458 एमएस कुल के मेरे परीक्षण में सबसे अधिक रूढ़िवादी "बेस सीपीयू" समय पर यह आधार कर रहा हूं, इसलिए 23218 एमएस / 25920000 = 0.18 μs। स्पष्ट 10x सुधार बहुत कुछ लगता है, लेकिन यह स्पष्ट रूप से बहुत छोटा है जब तक आप सैकड़ों हजारों पंक्तियों (617k पंक्तियों = 1 सेकंड की बचत) के साथ काम कर रहे हैं।
यहां तक कि इस छोटे से पूर्ण सुधार को देखते हुए, मेरी राय में, DateAdd
विधि जीतती है क्योंकि यह प्रदर्शन और स्पष्टता का सबसे अच्छा संयोजन है। जवाब है कि एक "जादू नंबर" की आवश्यकता होती है 0.50000004
किसी दिन (पांच शून्य या छह ???) किसी को काटने के लिए जा रहा है, साथ ही इसे समझना मुश्किल है।
अतिरिक्त नोट्स
जब मैं कुछ समय मैं परिवर्तन करने जा रहा हूँ मिल 0.50000004
करने के लिए '12:00:00.003'
और देखें कि यह कैसे करता है। यह उसी datetime
मूल्य में परिवर्तित हो जाता है और मुझे याद रखना बहुत आसान लगता है।
रुचि रखने वालों के लिए, उपरोक्त परीक्षण एक सर्वर पर चलाए गए थे, जहां @@ संस्करण निम्नलिखित देता है:
Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (Intel X86) Jul 9 2008 14:43:34 कॉपीराइट (c) 1988-2008 Microsoft NT मानक संस्करण Windows NT 5.2 पर (बिल्ड 3790: सर्विस पैक 2)