अपने प्रश्न में, आप कुछ परीक्षण जो आपने तैयार किए हैं, जहां आप "साबित" करते हैं कि अतिरिक्त विकल्प असतत कॉलम की तुलना में तेज है। मुझे संदेह है कि आपकी परीक्षा पद्धति कई मायनों में त्रुटिपूर्ण हो सकती है, क्योंकि @gbn और @srutzky ने अपना रुख किया है।
सबसे पहले, आपको यह सुनिश्चित करने की आवश्यकता है कि आप SQL सर्वर प्रबंधन स्टूडियो (या जो भी क्लाइंट आप उपयोग कर रहे हैं) का परीक्षण नहीं कर रहे हैं। उदाहरण के लिए, यदि आप SELECT *
3 मिलियन पंक्तियों वाली तालिका से चल रहे हैं, तो आप SSMS की SQL सर्वर से पंक्तियों को खींचने और उन्हें स्क्रीन पर प्रस्तुत करने की क्षमता का परीक्षण कर रहे हैं। आप कुछ का उपयोग करने के लिए बहुत बेहतर हैं जैसे SELECT COUNT(1)
कि नेटवर्क पर लाखों पंक्तियों को खींचने की आवश्यकता है, और उन्हें स्क्रीन पर प्रस्तुत करना।
दूसरा, आपको SQL सर्वर के डेटा कैश के बारे में पता होना चाहिए। आमतौर पर, हम भंडारण से डेटा को पढ़ने की गति का परीक्षण करते हैं, और उस डेटा को कोल्ड-कैश से संसाधित करते हैं (यानी SQL सर्वर के बफ़र्स खाली हैं)। कभी-कभी, यह आपके सभी परीक्षण को गर्म-कैश के साथ करने के लिए समझ में आता है, लेकिन आपको अपने परीक्षण को स्पष्ट रूप से ध्यान में रखना होगा।
शीत-कैश परीक्षण के लिए, आपको चलाने की आवश्यकता है CHECKPOINT
और DBCC DROPCLEANBUFFERS
परीक्षण के प्रत्येक रन से पहले।
आपके प्रश्न के बारे में पूछे जाने वाले परीक्षण के लिए, मैंने निम्नलिखित परीक्षण-बिस्तर बनाया:
IF COALESCE(OBJECT_ID('tempdb..#SomeTest'), 0) <> 0
BEGIN
DROP TABLE #SomeTest;
END
CREATE TABLE #SomeTest
(
TestID INT NOT NULL
PRIMARY KEY
IDENTITY(1,1)
, A INT NOT NULL
, B FLOAT NOT NULL
, C MONEY NOT NULL
, D BIGINT NOT NULL
);
INSERT INTO #SomeTest (A, B, C, D)
SELECT o1.object_id, o2.object_id, o3.object_id, o4.object_id
FROM sys.objects o1
, sys.objects o2
, sys.objects o3
, sys.objects o4;
SELECT COUNT(1)
FROM #SomeTest;
यह मेरी मशीन पर 260,144,641 की गिनती देता है।
"जोड़" विधि का परीक्षण करने के लिए, मैं चलाता हूं:
CHECKPOINT 5;
DBCC FREEPROCCACHE;
DBCC DROPCLEANBUFFERS;
SET STATISTICS IO, TIME ON;
GO
SELECT COUNT(1)
FROM #SomeTest st
WHERE (st.A + st.B + st.C + st.D) = 0;
GO
SET STATISTICS IO, TIME OFF;
संदेश टैब दिखाता है:
टेबल '#SomeTest'। स्कैन काउंट 3, लॉजिकल रीड 1322661, फिजिकल रीड्स 0, रीड-फॉरवर्ड रीड 1313877, लॉब लॉजिकल रीड्स 0, लॉब फिजिकल रीड्स 0, लोब रीड-फॉरवर्ड रीड्स 0।
SQL सर्वर निष्पादन समय: CPU समय = 49047 एमएस, बीता समय = 173451 एमएस।
"असतत कॉलम" परीक्षण के लिए:
CHECKPOINT 5;
DBCC FREEPROCCACHE;
DBCC DROPCLEANBUFFERS;
SET STATISTICS IO, TIME ON;
GO
SELECT COUNT(1)
FROM #SomeTest st
WHERE st.A = 0
AND st.B = 0
AND st.C = 0
AND st.D = 0;
GO
SET STATISTICS IO, TIME OFF;
संदेश टैब से फिर:
टेबल '#SomeTest'। स्कैन काउंट 3, लॉजिकल रीड 1322661, फिजिकल रीड्स 0, रीड-फॉरवर्ड रीड 1322661, लॉब लॉजिकल रीड्स 0, लॉब फिजिकल रीड्स 0, लोब रीड-फॉरवर्ड रीड्स 0।
SQL सर्वर निष्पादन समय: CPU समय = 8938 एमएस, बीता समय = 162581 एमएस।
ऊपर दिए गए आंकड़ों से आप दूसरे संस्करण को देख सकते हैं, 0 की तुलना में असतत कॉलम के साथ, बीता हुआ समय लगभग 10 सेकंड कम है, और सीपीयू का समय लगभग 6 गुना कम है। ऊपर दिए गए मेरे परीक्षणों में लंबी अवधि अधिकतर डिस्क से बहुत सी पंक्तियाँ पढ़ने का परिणाम है। यदि आप पंक्तियों की संख्या को 3 मिलियन तक गिरा देते हैं, तो आप देखते हैं कि अनुपात लगभग एक ही है, लेकिन बीता हुआ समय ध्यान देने योग्य है, क्योंकि डिस्क I / O का प्रभाव बहुत कम है।
"अतिरिक्त" विधि के साथ:
टेबल '#SomeTest'। स्कैन काउंट 3, लॉजिकल रीड्स 15255, फिजिकल रीड्स 0, रीड-फॉरवर्ड रीड्स 0, लॉब लॉजिकल रीड्स 0, लॉब फिजिकल रीड्स 0, लॉब रीड-फॉरवर्ड रीड्स 0।
SQL सर्वर निष्पादन समय: CPU समय = 499 ms, बीता समय = 256 ms।
"असतत कॉलम" विधि के साथ:
टेबल '#SomeTest'। स्कैन काउंट 3, लॉजिकल रीड्स 15255, फिजिकल रीड्स 0, रीड-फॉरवर्ड रीड्स 0, लॉब लॉजिकल रीड्स 0, लॉब फिजिकल रीड्स 0, लॉब रीड-फॉरवर्ड रीड्स 0।
SQL सर्वर निष्पादन समय: CPU समय = 94 एमएस, बीता हुआ समय = 53 एमएस।
इस परीक्षण के लिए वास्तव में बहुत बड़ा अंतर क्या होगा? एक उपयुक्त सूचकांक, जैसे:
CREATE INDEX IX_SomeTest ON #SomeTest(A, B, C, D);
"जोड़" विधि:
टेबल '#SomeTest'। स्कैन काउंट 3, लॉजिकल 14235 पढ़ता है, फिजिकल रीड्स 0, रीड-फॉरवर्ड रीड्स 0, लॉब लॉजिकल रीड्स 0, लॉब फिजिकल रीड्स 0, लॉब रीड-फॉरवर्ड रीड्स 0।
SQL सर्वर निष्पादन समय: CPU समय = 546 ms, बीता समय = 314 ms।
"असतत कॉलम" विधि:
टेबल '#SomeTest'। स्कैन काउंट 1, लॉजिकल रीड 3, फिजिकल रीड्स 0, रीड-फॉरवर्ड रीड्स 0, लॉब लॉजिकल रीड्स 0, लॉब फिजिकल रीड्स 0, लॉब रीड-फॉरवर्ड रीड्स 0।
SQL सर्वर निष्पादन समय: CPU समय = 0 ms, बीता समय = 0 ms।
प्रत्येक क्वेरी के लिए निष्पादन योजना (उपरोक्त सूचकांक के साथ जगह में) काफी बता रही है।
"जोड़" विधि, जिसे पूरे सूचकांक का स्कैन करना चाहिए:
और "असतत कॉलम" विधि, जो सूचकांक की पहली पंक्ति की ओर ले जा सकती है, जहां प्रमुख सूचकांक कॉलम A
शून्य है: