सूचकांक में कॉलम शामिल करने के लिए कठोर और तेज़ नियम


38

क्या यह तय करने के लिए कोई कठोर और तेज़ नियम है कि किस कॉलम और किस क्रम में इसे गैर-संकुलित सूचकांक में शामिल किया जाना चाहिए। मैं अभी इस पोस्ट को पढ़ रहा था https://stackoverflow.com/questions/1307990/why-use-the-include-clause-when-creating-an-index और मैंने पाया कि निम्नलिखित क्वेरी के लिए:

SELECT EmployeeID, DepartmentID, LastName
FROM Employee
WHERE DepartmentID = 5

पोस्टर ने सूचकांक को इस तरह बनाने का सुझाव दिया:

CREATE NONCLUSTERED INDEX NC_EmpDep 
  ON Employee(EmployeeID, DepartmentID)
  INCLUDE (Lastname)

यहाँ मेरा सवाल यह है कि हम इस तरह सूचकांक क्यों नहीं बना सकते हैं

CREATE NONCLUSTERED INDEX NC_EmpDep 
      ON Employee( EmployeeID, DepartmentID, LastName)

या

    CREATE NONCLUSTERED INDEX NC_EmpDep 
          ON Employee( EmployeeID, LastName)
INCLUDE (DepartmentID)

और कौन सी बात पोस्टर को अंतिम नाम स्तंभ को शामिल करने का निर्णय लेने की ओर ले जाती है। अन्य कॉलम क्यों नहीं? और कैसे तय किया जाए कि हमें कॉलम किस क्रम में रखना चाहिए?


3
INCLUDE में सामान्य रूप से वे फ़ील्ड होने चाहिए जिनके लिए आपको एक रिकॉर्ड की आवश्यकता होगी, अधिक डेटा प्राप्त करने के लिए आपको एक राउंड ट्रिप बचाकर। INCLUDE में खेतों का क्रम महत्वपूर्ण नहीं है।
जिम्बो

Ryk, व्यक्तिगत रूप से मुझे यह पोस्ट मददगार लगी।
जेसन यंग

मुझे यह सवाल मददगार लगता है। आइए
स्टेकिंग

जवाबों:


47

Marc_s द्वारा वह सूचकांक सुझाव गलत है। मैंने एक टिप्पणी जोड़ी है। (और यह मेरा उत्तर भी स्वीकार कर लिया गया था!)

इस प्रश्न का सूचकांक होगा

CREATE NONCLUSTERED INDEX NC_EmpDep 
  ON Employee(DepartmentID)
  INCLUDE (Lastname, EmployeeID)

एक सूचकांक आम तौर पर है

CREATE INDEX <name> ON <table> (KeyColList) INCLUDE (NonKeyColList)

कहा पे:

  • KeyColList = प्रमुख कॉलम = पंक्ति प्रतिबंध और प्रसंस्करण के लिए उपयोग किया जाता है
    , जहां, आदेश, आदेश द्वारा, ग्रुप द्वारा आदि
  • NonKeyColList = गैर-कुंजी कॉलम = चयन / प्रतिबंध के बाद SELECT और एकत्रीकरण (जैसे SUM (कॉल)) में उपयोग किया जाता है

+1 - मैं सहमत हूं (मेरे ans देखें) कि ओपी में नमूना सूचकांक क्वेरी के लिए बेकार हैं!
जेएनके

महान! बस एक बात और क्या KeyColList और NonKeyColList के आदेश का फैसला करेगा। क्या आप सिर्फ मेरे उदाहरण से समझा सकते हैं? मान लीजिए कि अब मेरी क्वेरी SELECT EmployeeID, DepartmentID, LastName FROM EmployeeWHERE DepartmentID = 5, StateID = 4 है, तो अब सूचकांक कैसा होना चाहिए?

@ नकली - NonKeyColListआदेश कोई फर्क नहीं पड़ता। KeyColListआदेश आवृत्ति के क्रम में होना चाहिए जो आप उन्हें प्रश्नों में उपयोग करने की अपेक्षा करते हैं। नीचे दिए गए मेरे उत्तर पर मेरे नोट्स देखें, लेकिन यह Last Name, First Name, Middile Initialएक फोन बुक की तरह है। दूसरे फ़ील्ड को खोजने के लिए आपको पहले फ़ील्ड की आवश्यकता है।
जेएनके

@ क्या हमें वास्तव में सूची में शामिल कर्मचारी की आवश्यकता है? जैसे कि हमने EmployeeID कॉलम पर क्लस्टर किया हुआ इंडेक्स है और इसके ऊपर अगर हम DeptId कॉलम पर एक गैर-अनुक्रमित इंडेक्स बनाते हैं, तो NonClustered इंडेक्स में पहले से ही क्लस्टरिंग कुंजी का संदर्भ होता है, जो INCLUDE सूची में कुंजी को क्लस्टर करने सहित NonClustered इंडेक्स संरचना में शामिल है। टी किसी भी लाभ जोड़ें।
विश्वनाथन अय्यर

1
@ViswanathanIyer इसे वास्तविक ऑन-डिस्क स्टोरेज से दो बार नहीं जोड़ा जाएगा: SQL सर्वर इसका पता लगाता है। इसलिए इसकी जरूरत नहीं है लेकिन यह चीजों को स्पष्ट करता है। हालाँकि, हम प्रश्न में किसी भी संकुल अनुक्रमणिका के बारे में नहीं जानते हैं, इसलिए यह कोई भी मानने के लिए सुरक्षित नहीं है।
gbn

19

JNK और gbn ने शानदार उत्तर दिए हैं, लेकिन यह बड़ी तस्वीर पर विचार करने के लायक है - न कि केवल एक क्वेरी पर ध्यान केंद्रित करने के लिए। हालाँकि यह विशेष क्वेरी एक इंडेक्स (# 1) से लाभान्वित हो सकती है:

Employee(DepartmentID) INCLUDE (Lastname, EmployeeID)

यदि क्वेरी थोड़ी बदल जाती है तो यह सूचकांक बिल्कुल भी मदद नहीं करता है, जैसे:

SELECT EmployeeID, DepartmentID, LastName
FROM Employee
WHERE DepartmentID = 5 AND LastName = 'Smith'

इसके लिए सूचकांक (# 2) की आवश्यकता होगी:

Employee(DepartmentID, LastName) INCLUDE (EmployeeID)

कल्पना कीजिए कि आपके पास विभाग में 1,000 कर्मचारी थे। सभी स्मिथों को खोजने के लिए # 1 इंडेक्स का उपयोग करते हुए, आपको विभाग 5 में सभी 1,000 पंक्तियों के माध्यम से तलाश करना होगा, क्योंकि इसमें शामिल कॉलम कुंजी का हिस्सा नहीं हैं। इंडेक्स # 2 का उपयोग करते हुए, आप सीधे विभाग 5, लास्ट नेम स्मिथ की तलाश कर सकते हैं।

सूचकांक # 2 इस प्रकार प्रश्नों की एक विस्तृत श्रृंखला की सेवा करने में अधिक उपयोगी है - लेकिन लागत एक अधिक फूला हुआ सूचकांक कुंजी है, जो सूचकांक के गैर-पत्ती पृष्ठों को बड़ा कर देगा। हर प्रणाली अलग होगी, इसलिए यहां कोई नियम-आधारित अंगूठा नहीं है।


एक साइड नोट के रूप में, यह इंगित करने के लायक है कि यदि कर्मचारी इस तालिका के लिए क्लस्टरिंग कुंजी है - एक संकुल सूचकांक मान रहा है - तो आपको कर्मचारी को शामिल करने की आवश्यकता नहीं है - यह सभी गैर-क्लस्टर किए गए अनुक्रमित में मौजूद है, जिसका अर्थ सूचकांक # 2 बस हो सकता है होना

Employee(DepartmentID, LastName)

2
अधिक उपयोगी जानकारी के लिए +1। आपके अंतिम बिंदु के लिए, मैंने इसका परीक्षण किया और INCLUDE में कर्मचारी के स्पष्ट उपयोग को वास्तव में अनदेखा किया गया है (सूचकांक के आकार के आधार पर) यदि कर्मचारी वर्ग का सूचकांक है। यह अधिक स्पष्ट है, हालांकि मुझे लगता है कि कोई जगह नहीं है।
gbn

1
मैं बिल्कुल सहमत हूँ - यह हमेशा स्पष्ट होना बेहतर है, खासकर अगर यह कुछ भी नहीं खर्च करता है!

1
बस मामले में ... मेरा मतलब है कि मैंने INCLUDE (स्पष्ट रूप से कर्मचारी नहीं) में संकुल कुंजी का परीक्षण किया है और यह कोई स्थान नहीं जोड़ता है। प्रमुख स्तंभों में यह करता है।
gbn

@ हां, क्लस्टर कुंजी को केवल इंडेक्स के लीफ-लेवल में रहने की आवश्यकता है, जो कि INCLUDE कॉलम के बीच है। इसे इंडेक्स की में ले जाने का मतलब है कि यह नॉन-लीफ पेजों में भी मौजूद होगा। इसका परिणाम थोड़ा ब्लोट होगा, लेकिन एक भयानक राशि नहीं है (मध्यवर्ती स्तर के पृष्ठों पर, आप एक पूर्णांक स्तर पर एक और 4 बाइट्स जोड़ेंगे, एक पूर्णांक मानकर)।

यह महान उत्तर है जिसमें इस लेख में वर्णित कुछ प्रभाव शामिल हैं: sqlperformance.com/2014/07/sql-indexes/… यदि आपकी क्वेरी बदलती है तो अपने अनुक्रमित की आवश्यकताओं को पूरा करें। आप जिम के उत्तर के साथ बेहतर हो सकते हैं, लेकिन आप @ जवाब के साथ बेहतर किराया दे सकते हैं।
जॉन उर्फ ​​हॉट

7

मुझे यकीन नहीं है कि आपको वह पहला कैसे मिला। मेरे लिए, उस क्वेरी के लिए, मैं उपयोग करूंगा:

CREATE NONCLUSTERED INDEX NC_EmpDep 
  ON Employee(DepartmentID)
  INCLUDE (EmployeeID, Lastname)

SQL में बहुत ज्यादा कुछ के लिए "हार्ड और फास्ट नियम" नहीं है।

लेकिन, आपके उदाहरण के लिए, केवल एक ही क्षेत्र सूचकांक का उपयोग करेगा DepartmentIDक्योंकि यह WHEREखंड में है।

अन्य क्षेत्रों को वहां से आसानी से पहुंचने की आवश्यकता है। आप DepartmentIDउसके आधार पर चयन करते हैं INCLUDEकि उन क्षेत्रों को सूचकांक के पत्ती नोड पर रखा गया है।

आप अपने अन्य उदाहरणों का उपयोग नहीं करना चाहते क्योंकि वे इस सूचकांक के लिए काम नहीं करेंगे।

एक फोन बुक की तरह एक सूचकांक के बारे में सोचो। ज्यादातर फोन बुक लास्ट नेम, फर्स्ट नेम, मिडिल इनिशियल द्वारा ऑर्डर की जाती हैं। यदि आप किसी का पहला नाम जानते हैं, लेकिन उनका अंतिम नाम नहीं है, तो फोन बुक आपके लिए अच्छा नहीं है क्योंकि आप फोन बुक के सूचकांक के आदेश के आधार पर पहले नाम नहीं खोज सकते हैं।

INCLUDEखेतों फोन नंबर, पता, आदि पुस्तक में प्रत्येक प्रविष्टि के लिए अन्य जानकारी की तरह हैं।

संपादित करें:

आगे स्पष्ट करने के लिए कि क्यों न उपयोग किया जाए:

CREATE NONCLUSTERED INDEX NC_EmpDep 
          ON Employee( EmployeeID, LastName)
INCLUDE (DepartmentID)

यह इंडेक्स केवल तभी उपयोगी है जब आपके पास EmployeeIDया बीओटीएच EmployeeID और LastNameआपके WHEREक्लॉज में हों। यह इस क्वेरी के लिए आपके लिए आवश्यक OPPOSITE का बहुत अधिक हिस्सा है ।


@ajbeaven यह सच है, यही वजह है कि मैंने जो टिप्पणी संपादन में डाली है, उसमें कहा गया है कि आपको EITHER के कर्मचारी या दोनों कॉलम चाहिए।
जेएनके

durr सॉरी ग़लतफ़हमी :(
ajbeaven

0

मुझे लगता है कि आप अभी भी (कर्मचारी_आईडी, डिपार्टमेंट_आईडी) सूचकांक का उपयोग करने में सक्षम हो सकते हैं, लेकिन आपको उस वाक्यांश में 'डमी' लाइन शामिल करनी होगी, जैसे: "कर्मचारी_आईडी = कर्मचारी_आईडी)

  • पर एक इंडेक्स होने पर
  • केवल एक विभाग_ पर खोज / प्रतिबंधित करना
  • यह जानते हुए कि यह गलत क्रम से सूचकांक का उपयोग नहीं करेगा (या अब तक चीजें बदल गई हैं, और निम्नलिखित "ट्रिक" की अब आवश्यकता नहीं है। मैं "पुराना" हूं?)
  • "पुराने" tricK का उपयोग करें?

    एम्प्लॉई एम्पायर से चुनें
    जहाँ emp.employee_id = emp.employee_id
    और emp.depbox_id = 5

(इसलिए मैं लास्टनाम के यहाँ शामिल हिस्से पर ध्यान नहीं दे रहा हूँ, लेकिन हाँ पर / या कुंजी का उपयोग नहीं किया जा रहा है।)

सधन्यवाद,

Miguell


2
नहीं, वह बेकार है और कुशल नहीं है।
ypercube y

विशेष रूप से, विभाग के सभी उदाहरणों को खोजने के लिए प्रत्येक कर्मचारी आईडी को खोजने के लिए उसे अभी भी एक इंडेक्स स्कैन करना होगा।
मार्क सोउल

अब विपरीत मामले पर विचार करें (इंडेक्स डिपार्टमेंट_ड, एंप्लॉयी_आईडी पर है)। जाहिर है कि अब किसी विशेष विभाग को ढूंढना आसान है, लेकिन यह भी ध्यान दें कि किसी विशेष कर्मचारी को खोजने के लिए, SQL को किसी विशेष कर्मचारी के लिए सभी पंक्तियों को खोजने के लिए केवल 5 विभागों के माध्यम से स्कैन करना होगा।
मार्क सोउल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.