Database
 sql >> डेटाबेस >  >> RDS >> Database

FORMAT() अच्छा और सब कुछ है, लेकिन…

वापस जब SQL Server 2012 अभी भी बीटा में था, मैंने नए FORMAT() . के बारे में ब्लॉग किया था फ़ंक्शन:SQL सर्वर v.Next (Denali):CTP3 T-SQL एन्हांसमेंट:FORMAT ()।

उस समय, मैं नई कार्यक्षमता को लेकर इतना उत्साहित था, कि मैंने कोई प्रदर्शन परीक्षण करने के बारे में सोचा भी नहीं था। मैंने इसे एक और हालिया ब्लॉग पोस्ट में संबोधित किया था, लेकिन पूरी तरह से डेटाटाइम से स्ट्रिपिंग टाइम के संदर्भ में:डेटाटाइम से ट्रिमिंग टाइम - एक फॉलो-अप।

पिछले हफ्ते, मेरे अच्छे दोस्त जेसन हॉर्नर (ब्लॉग | @jasonhorner) ने मुझे इन ट्वीट्स से ट्रोल किया:

इसके साथ मेरी समस्या बस यह है कि FORMAT() सुविधाजनक दिखता है, लेकिन यह अन्य दृष्टिकोणों की तुलना में बेहद अक्षम है (ओह और वह AS VARCHAR बात भी खराब है)। यदि आप इसे ओसी-ट्वोसी कर रहे हैं और छोटे परिणामों के लिए, मैं इसके बारे में ज्यादा चिंता नहीं करता; लेकिन बड़े पैमाने पर, यह काफी महंगा हो सकता है। एक उदाहरण से समझाता हूँ। सबसे पहले, आइए 1000 छद्म यादृच्छिक तिथियों के साथ एक छोटी तालिका बनाएं:

SELECT TOP (1000) d = DATEADD(DAY, CHECKSUM(NEWID())%1000, o.create_date)
  INTO dbo.dtTest
  FROM sys.all_objects AS o
  ORDER BY NEWID();
GO
CREATE CLUSTERED INDEX d ON dbo.dtTest(d);

अब, इस तालिका के डेटा के साथ कैश को प्राइम करें, और उन तीन सामान्य तरीकों का वर्णन करें जो लोग केवल समय पर प्रस्तुत करते हैं:

SELECT d, 
  CONVERT(DATE, d), 
  CONVERT(CHAR(10), d, 120),
  FORMAT(d, 'yyyy-MM-dd')
FROM dbo.dtTest;

अब, इन विभिन्न तकनीकों का उपयोग करने वाली अलग-अलग क्वेरी करते हैं। हम उन्हें हर 5 बार चलाएंगे और हम निम्नलिखित विविधताएं चलाएंगे:

  1. सभी 1,000 पंक्तियों का चयन करना
  2. क्लस्टर इंडेक्स की के अनुसार टॉप (1) का चयन करना
  3. एक वैरिएबल को असाइन करना (जो एक पूर्ण स्कैन के लिए बाध्य करता है, लेकिन SSMS रेंडरिंग को प्रदर्शन में हस्तक्षेप करने से रोकता है)

यहाँ स्क्रिप्ट है:

-- select all 1,000 rows
GO
SELECT d FROM dbo.dtTest;
GO 5
SELECT d = CONVERT(DATE, d) FROM dbo.dtTest;
GO 5
SELECT d = CONVERT(CHAR(10), d, 120) FROM dbo.dtTest;
GO 5
SELECT d = FORMAT(d, 'yyyy-MM-dd') FROM dbo.dtTest;
GO 5
 
-- select top 1
GO
SELECT TOP (1) d FROM dbo.dtTest ORDER BY d;
GO 5
SELECT TOP (1) CONVERT(DATE, d) FROM dbo.dtTest ORDER BY d;
GO 5
SELECT TOP (1) CONVERT(CHAR(10), d, 120) FROM dbo.dtTest ORDER BY d;
GO 5
SELECT TOP (1) FORMAT(d, 'yyyy-MM-dd') FROM dbo.dtTest ORDER BY d;
GO 5
 
-- force scan but leave SSMS mostly out of it
GO
DECLARE @d DATE;
SELECT @d = d FROM dbo.dtTest;
GO 5
DECLARE @d DATE;
SELECT @d = CONVERT(DATE, d) FROM dbo.dtTest;
GO 5
DECLARE @d CHAR(10);
SELECT @d = CONVERT(CHAR(10), d, 120) FROM dbo.dtTest;
GO 5
DECLARE @d CHAR(10);
SELECT @d = FORMAT(d, 'yyyy-MM-dd') FROM dbo.dtTest;
GO 5

अब, हम निम्न क्वेरी के साथ प्रदर्शन को माप सकते हैं (मेरा सिस्टम बहुत शांत है; आपके लिए, आपको केवल execution_count की तुलना में अधिक उन्नत फ़िल्टरिंग करने की आवश्यकता हो सकती है ):

SELECT 
  [t] = CONVERT(CHAR(255), t.[text]), 
  s.total_elapsed_time, 
  avg_elapsed_time = CONVERT(DECIMAL(12,2),s.total_elapsed_time / 5.0),
  s.total_worker_time, 
  avg_worker_time = CONVERT(DECIMAL(12,2),s.total_worker_time / 5.0),
  s.total_clr_time
FROM sys.dm_exec_query_stats AS s 
CROSS APPLY sys.dm_exec_sql_text(s.[sql_handle]) AS t
WHERE s.execution_count = 5
  AND t.[text] LIKE N'%dbo.dtTest%'
ORDER BY s.last_execution_time;

मेरे मामले में परिणाम काफी सुसंगत थे:

<वें colspan=3>अवधि (माइक्रोसेकंड)
क्वेरी (छोटा गया)
कुल_बीता हुआ औसत_बीता हुआ total_clr
1,000 पंक्तियां चुनें SELECT d FROM dbo.dtTest ORDER BY d; 1,170 234.00 0
SELECT d = CONVERT(DATE, d) FROM dbo.dtTest ORDER BY d; 2,437 487.40 0
SELECT d = CONVERT(CHAR(10), d, 120) FROM dbo.dtTest ORD ... 151,521 30,304.20 0
SELECT d = FORMAT(d, 'yyyy-MM-dd') FROM dbo.dtTest ORDER ... 240,152 48,030.40 107,258
SELECT TOP (1) SELECT TOP (1) d FROM dbo.dtTest ORDER BY d; 251 50.20 0
SELECT TOP (1) CONVERT(DATE, d) FROM dbo.dtTest ORDER BY ... 440 88.00 0
SELECT TOP (1) CONVERT(CHAR(10), d, 120) FROM dbo.dtTest ... 301 60.20 0
SELECT TOP (1) FORMAT(d, 'yyyy-MM-dd') FROM dbo.dtTest O ... 1,094 218.80 589
Assign variable DECLARE @d DATE; SELECT @d = d FROM dbo.dtTest; 639 127.80 0
DECLARE @d DATE; SELECT @d = CONVERT(DATE, d) FROM dbo.d ... 644 128.80 0
DECLARE @d CHAR(10); SELECT @d = CONVERT(CHAR(10), d, 12 ... 1,972 394.40 0
DECLARE @d CHAR(10); SELECT @d = FORMAT(d, 'yyyy-MM-dd') ... 118,062 23,612.40 98,556

 

And to visualize the avg_elapsed_time . की कल्पना करने के लिए आउटपुट (विस्तार करने के लिए क्लिक करें):

FORMAT() स्पष्ट रूप से हारने वाला है:avg_elapsed_time परिणाम (माइक्रोसेकंड)

इन परिणामों से हम क्या सीख सकते हैं (फिर से):

  1. सबसे पहले और सबसे महत्वपूर्ण, FORMAT() महंगा है
  2. FORMAT() स्वीकार्य रूप से, अधिक लचीलापन प्रदान कर सकते हैं और अधिक सहज ज्ञान युक्त तरीके दे सकते हैं जो सी # जैसी अन्य भाषाओं के अनुरूप हैं। हालाँकि, इसके ओवरहेड के अलावा, और जबकि CONVERT() स्टाइल नंबर गुप्त और कम विस्तृत हैं, आपको वैसे भी पुराने दृष्टिकोण का उपयोग करना पड़ सकता है, क्योंकि FORMAT() केवल SQL Server 2012 और नए में मान्य है।
  3. यहां तक ​​कि स्टैंडबाय CONVERT() विधि काफी महंगी हो सकती है (हालांकि केवल गंभीर रूप से उस मामले में जहां एसएसएमएस को परिणाम प्रस्तुत करना था - यह स्पष्ट रूप से दिनांक मानों की तुलना में स्ट्रिंग को अलग तरीके से संभालता है)।
  4. डेटाटाइम मान को सीधे डेटाबेस से बाहर निकालना हमेशा सबसे कुशल था। आपको प्रस्तुतिकरण स्तर पर वांछित तिथि को प्रारूपित करने के लिए आपके आवेदन के लिए अतिरिक्त समय लेना चाहिए - यह अत्यधिक संभावना है कि आप एसक्यूएल सर्वर को सुंदर प्रारूप में शामिल नहीं करना चाहते हैं (और वास्तव में कई तर्क देंगे कि यह वह जगह है जहां वह तर्क हमेशा संबंधित होता है)।

हम यहां केवल माइक्रोसेकंड की बात कर रहे हैं, लेकिन हम भी केवल 1,000 पंक्तियों की बात कर रहे हैं। इसे अपने वास्तविक तालिका आकारों तक बढ़ाएं, और गलत स्वरूपण दृष्टिकोण चुनने का प्रभाव विनाशकारी हो सकता है।

यदि आप इस प्रयोग को अपनी मशीन पर आज़माना चाहते हैं, तो मैंने एक नमूना स्क्रिप्ट अपलोड की है:FormatIsNiceAndAllbut.sql_.zip


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Java से 4D से कनेक्ट करना

  2. डेटाटाइम के बजाय दिनांक और समय से निपटना

  3. ऑप्टिमाइज़ेशन थ्रेशोल्ड - डेटा को समूहीकृत और एकत्र करना, भाग 3

  4. SQL वर्कलोड विश्लेषण आपकी कैसे मदद कर सकता है?

  5. एक्शन शेड्यूलर से पोस्ट और टिप्पणियां हटाएं