उच्च चयनात्मकता और कम चयनात्मकता क्षेत्रों के साथ एक समग्र सूचकांक क्रम में फ़ील्ड क्रम


11

मेरे पास 3 बिलियन से अधिक पंक्तियों के साथ SQL सर्वर तालिका है। मेरी क्वेरी में से एक को बहुत लंबा समय लगता है इसलिए मैं इसे अनुकूलित करने पर विचार कर रहा हूं। प्रश्न इस तरह दिखता है:

SELECT [Enroll_Date]
      ,Count(*) AS [Record #]
      ,Count(Distinct UserID) AS [User #]
  FROM UserTable
  GROUP BY [Enroll_Date]

[Enroll_Date] 50 से कम संभावित मानों वाला एक कम चयनात्मकता स्तंभ है, जबकि UserID स्तंभ एक उच्च चयनात्मकता स्तंभ है जिसमें 200 मिलियन से अधिक भिन्न मान हैं। मेरे शोध के आधार पर मेरा मानना ​​है कि मुझे इन दो स्तंभों पर एक गैर-संकुल संयुक्त सूचकांक बनाना चाहिए, और सिद्धांत रूप में उच्च चयनात्मकता स्तंभ पहला स्तंभ होना चाहिए। लेकिन मुझे यकीन नहीं है कि मेरे मामले में, यह काम करेगा क्योंकि मैं समूह में कम चयनात्मकता कॉलम का उपयोग कर रहा हूं।

इस तालिका में कोई संकुल सूचकांक नहीं है।


क्या आप वास्तविक निष्पादन योजना xml पोस्ट कर सकते हैं (pastebin का उपयोग करें और इसे यहां लिंक करें)? आप किस SQL ​​सर्वर का उपयोग कर रहे हैं?
परिजन शाह

3
अत्यधिक चुनिंदा कॉलम वाला इंडेक्स पहले विशिष्ट क्वेरी के लिए बेकार होगा।
ypercube y

यह एक सूचकांक (सामान्य रूप से) में पहले कुंजी स्तंभ के रूप में उच्च चयनात्मकता कॉलम का उपयोग करने के लिए सबसे अच्छा अभ्यास है। इस परिदृश्य में, जैसा कि आपने अनुमान लगाया था, यह आपकी बिल्कुल मदद नहीं करता है। आपको दो अनुक्रमणिकाओं की आवश्यकता हो सकती है! क्या होता है जब आप पहले और user_id दूसरे का नामांकन_ उपयोग करते हैं?
पॉलबारिन

जवाबों:


12

@ AaronBertrand के समाधान के विकल्प के रूप में (यदि आप अनुक्रमित दृश्य बनाना नहीं चाहते या नहीं बना सकते), मैं आपको एक सूचकांक बनाने की सलाह दूंगा (Enroll_Date, UserID)। यदि आपकी टेबल पर इस प्रकार का प्रश्न बहुत ही सामान्य है, तो संभवतः यह आपका क्लस्टर इंडेक्स भी होना चाहिए।

मैं आमतौर पर उच्च-चयनात्मकता सूचकांक को एक सामान्य "सर्वोत्तम अभ्यास" के रूप में अनुशंसित नहीं करता, बल्कि यह देखें कि कौन सा सूचकांक आपकी क्वेरी को सबसे अच्छा प्रदर्शन देगा।

एक इंडेक्स (Enroll_Date, UserID)स्ट्रीम एग्रीगेट्स के साथ आपकी क्वेरी को अत्यधिक अनुकूलित, गैर-अवरुद्ध क्वेरी प्लान देगा।

स्ट्रीम कुल क्वेरी योजना

इस संदर्भ में "नॉन-ब्लॉकिंग" का अर्थ है कि क्वेरी को डेटा की किसी भी महत्वपूर्ण मात्रा को बफर करने की आवश्यकता नहीं है (जैसे, उदाहरण के लिए, एक सॉर्ट या हैश एग्रीगेट), जिसका अर्थ है कि यह (ए) तुरंत पंक्तियों को वापस करना शुरू कर देता है, और ( ख) व्यावहारिक रूप से कोई भी काम करने वाली मेमोरी नहीं खाता है।


मजेदार, 4 सेकंड अलग और एक ही जवाब।
usr

11

हारून जवाब एक महान समाधान है। मैं इस प्रश्न का उत्तर दूंगा कि आप उस दृष्टिकोण को नहीं लेना चाहते हैं।

आपके द्वारा पोस्ट की गई क्वेरी को आमतौर पर पहले समूहीकरण द्वारा निष्पादित किया जाएगा (Enroll_Date, UserID), फिर फिर से (Enroll_Date)। यह अनुकूलन SQL सर्वर 2012 के लिए नया है। यह एकल के मामले में प्रभावी होता है COUNT DISTINCT

विशिष्ट क्रम में उन दो कॉलमों पर एक इंडेक्स (Enroll_Date, UserID)एक कुशल योजना प्राप्त करने के लिए पर्याप्त होगा जो फ़ंड को लगातार दो स्ट्रीम एग्रीगेट्स में स्कैन करता है। विपरीत क्रम उस योजना को सक्षम नहीं करेगा।

इसलिए, आदेश का उपयोग करें (Enroll_Date, UserID)। आपके पास यहां कोई विकल्प नहीं है।


5 सेकंड अलग और एक ही समाधान। अच्छा खेला, सर। :)
डैनियल Hutmacher

@DanielHutmacher OMG, क्या हम तीसरी बार अपनी पोस्ट से लगभग मिलान करेंगे? आप को +1! मैं एक समान जवाब कैसे नहीं दे सकता था?
usr

मैट्रिक्स में गड़बड़। :)
डैनियल Hutmacher

आपका बहुत बहुत धन्यवाद। मैं इंडेक्स बना रहा हूं और सुधार होने के बाद इसे पोस्ट करूंगा। सर्वर संस्करण AWS पर Microsoft SQL Server 2008 R2 है, लेकिन मुझे लगता है कि यह अभी भी परवाह किए बिना केवल संकेत है।
Thinkinger

@Thinkinger मामले में आप हारून के दृष्टिकोण को स्वीकार नहीं कर रहे हैं जो आपको एक कठिन विकल्प मिल गया है :)
usr

11

अनुक्रमित दृश्य के लिए एक आदर्श परिदृश्य की तरह लगता है, जो आपको क्वेरी समय के बजाय गणना समय पर गणना और समुच्चय के लिए भुगतान करने की अनुमति देता है।

CREATE VIEW dbo.MyIndexedView
WITH SCHEMABINDING
AS 
  SELECT Enroll_Date, UserID, RawCount = COUNT_BIG(*)
  FROM dbo.UserTable
  GROUP BY Enroll_Date, UserID;
GO

CREATE UNIQUE CLUSTERED INDEX CIX_miv ON dbo.MyIndexedView(Enroll_Date, UserID);

इसे बनाने में कुछ समय लगेगा, और निश्चित रूप से बेस टेबल पर एक सूचकांक की तरह, सभी डीएमएल संचालन में रखरखाव की आवश्यकता होगी।

अब इस दृश्य के विरुद्ध क्वेरी काफी हद तक समान होगी - दृश्य में प्रत्येक पंक्ति अब एक अलग उपयोगकर्ता / दिनांक कॉम्बो का प्रतिनिधित्व करती है, जिससे कि आंकड़ा एक एकल COUNT (*) द्वारा गणना की जा सकती है, जबकि आधार तालिका में पंक्तियों की कुल संख्या है आपके लिए पहले से ही आंशिक रूप से एकत्र किया गया है, अब आपको बस प्रति दिनांक SUM का उपयोग करके उन्हें जोड़ना होगा:

SELECT Enroll_Date, 
  [Record #] = SUM(RawCount),
  [User #] = COUNT(*)
FROM dbo.MyIndexedView WITH (NOEXPAND)
GROUP BY Enroll_Date; 

यह और यह याद रखने के बाद NOEXPAND संकेत मिला ।

मैं आपको बिना किसी संदेह के बता सकता हूं कि यह क्वेरी आपकी वर्तमान क्वेरी (लेकिन कितनी नहीं) से भी तेज होगी, सिवाय उस दुर्लभ मामले में जहां आपके पास प्रत्येक तिथि के लिए ठीक एक उपयोगकर्ता है (जिस स्थिति में डेटा की समान मात्रा होगी) पढ़ा जा सकता है) और हम जिन स्तंभों के बारे में जानते हैं, वे आधार तालिका के सूचकांक में एकमात्र स्तंभ हैं। क्या रीड टाइम के दौरान प्रदर्शन का प्रदर्शन अतिरिक्त काम के लायक है, जो आपके कार्यभार के लेखन हिस्से को प्रभावित करेगा, ऐसा कुछ है जो हम आपको नहीं बता सकते हैं - आपको इसे व्यापार-नापने के लिए परीक्षण करना होगा (कोई सूचकांक मुक्त नहीं है)।

और यदि आप अक्सर विशिष्ट, अच्छी तरह से परिभाषित श्रेणियों (कहते हैं, वर्तमान तिमाही या वर्ष के लिए) के लिए Enroll_Date के खिलाफ एक ही आम का उपयोग करते हैं, तो आप मिलान फ़िल्टर किए गए अनुक्रमित जोड़ सकते हैं जो कि I / O को और भी कम कर सकते हैं (लेकिन हमेशा हमेशा अदला - बदली)।

आप बेस टेबल पर क्लस्टर इंडेक्स लगाने पर भी विचार कर सकते हैं। यह उन बहुत ही दुर्लभ उपयोग मामलों में से एक नहीं लगता है जो एक ढेर से लाभान्वित होते हैं।


मैंने अभी अपने आईटी के साथ पुष्टि की है और ऐसा लगता है कि मैं इस तरह का दृश्य नहीं बना सकता। लेकिन फिर भी आपकी सलाह पर ध्यान देना चाहिए, और यह दूसरों की मदद करेगा जो इसका उपयोग कर सकते हैं।
Thinkinger

1
क्या आपका आईटी यह सोचता है कि बेस टेबल पर अनुक्रमित दृश्य और अतिरिक्त या अलग-अलग इंडेक्स के बीच एक महत्वपूर्ण अंतर है? जुझारू नहीं, सिर्फ जिज्ञासु हैं, क्योंकि बहुत से लोगों को अनुक्रमित विचारों के बारे में गलत धारणाएं हैं। मैं उन्हें एक अतिरिक्त, स्किनियर क्लस्टर टेबल पर अनुक्रमणिका के रूप में सोचना पसंद करता हूं, लेकिन कम पंक्तियों के साथ।
हारून बर्ट्रेंड

@ थिंकिंगर भी, अनुक्रमित विचार केवल ईई नहीं हैं। अनुक्रमित दृश्य मिलान केवल ईई है। आप सीधे NOEXPAND का उपयोग करके उन्हें निशाना बना सकते हैं।
usr
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.