निष्पादन योजना INDEX का उपयोग नहीं कर रही है, यह टेबल स्कैन का उपयोग करती है


9

मुझे पता है कि जब एक इंडेक्स या टेबल स्कैन का उपयोग करने की बात आती है, तो SQL सर्वर आंकड़ों का उपयोग करके यह देखता है कि कौन सा बेहतर है।

मेरे पास 20 मिलियन पंक्तियों वाली एक तालिका है। मेरे पास (SnapshotKey, उपाय) और इस क्वेरी पर एक सूचकांक है:

select Measure, SnapshotKey, MeasureBand
from t1
where Measure = 'FinanceFICOScore'
group by Measure, SnapshotKey, MeasureBand

क्वेरी 500k पंक्तियों को लौटाती है। इसलिए क्वेरी तालिका की केवल 2.5% पंक्तियों का चयन करती है।

सवाल यह है कि SQL सर्वर के पास मेरे पास मौजूद गैर-अनुक्रमित सूचकांक का उपयोग क्यों नहीं करता है, और इसके बजाय एक टेबल स्कैन का उपयोग करता है?

आंकड़े अपडेट किए जाते हैं।

यह बताने के लिए अच्छा है कि क्वेरी का प्रदर्शन हालांकि अच्छा है।

टेबल स्कैन

टेबल स्कैन

मजबूर सूचकांक

बल सूचकांक

तालिका / सूचकांक संरचना

CREATE TABLE [t1](
    [SnapshotKey] [int] NOT NULL,
    [SnapshotDt] [date] NOT NULL,
    [Measure] [nvarchar](30) NOT NULL,
    [MeasureBand] [nvarchar](30) NOT NULL,
    -- and many more fields
) ON [PRIMARY]

टेबल पर कोई पीके नहीं है, क्योंकि यह एक डेटा वेयरहाउस है।

CREATE NONCLUSTERED INDEX [nci_SnapshotKeyMeasure] ON [t1]
(
    [SnapshotKey] ASC,
    [Measure] ASC
)

जवाबों:


16

यदि आप कई पंक्तियों और / या पंक्तियों को बहुत व्यापक हैं, तो इंडेक्स की तलाश सबसे अच्छा विकल्प नहीं हो सकता है। यदि आपका सूचकांक कवर नहीं कर रहा है तो लुकअप महंगा हो सकता है। # 2 यहाँ देखें

आपके परिदृश्य में, क्वेरी ऑप्टिमाइज़र का अनुमान है कि एकल स्कैन की तुलना में 50,000 व्यक्तिगत लुकअप करना अधिक महंगा होगा। स्कैन और तलाश के बीच ऑप्टिमाइज़र की पसंद (क्वेरी द्वारा आवश्यक कॉलम के लिए RID लुकअप के साथ, लेकिन नॉनस्ट्रेस्ड इंडेक्स में मौजूद नहीं) प्रत्येक विकल्प की अनुमानित लागत पर आधारित है ।

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

अब, ऑप्टिमाइज़र द्वारा उपयोग किया जाने वाला लागत मॉडल मान्यताओं और "मैजिक नंबरों" पर आधारित है, जो आपके सिस्टम के प्रदर्शन विशेषताओं से मेल खाने की संभावना नहीं है। विशेष रूप से, मॉडल में बनाई गई एक धारणा यह है कि क्वेरी पहले से ही आवश्यक डेटा या इंडेक्स पेजों में से किसी के साथ निष्पादित करना शुरू कर देती है। एक और यह है कि क्रमिक I / O (स्कैन के लिए अपेक्षित) RID लुकअप के लिए यादृच्छिक I / O पैटर्न से सस्ता है। इस तरह के विस्तार में जाने के लिए कई अन्य मान्यताओं और चेतावनी भी हैं।

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

मॉडल की सीमाएं और अन्य कारक कभी-कभी इसका मतलब होगा कि ऑप्टिमाइज़र एक ऐसी योजना चुनता है जो वास्तव में नहीं है, "बिल्कुल पर्याप्त"। आप रिपोर्ट करते हैं कि "प्रदर्शन अच्छा है", इसलिए यहां ऐसा नहीं लगता है।


9

आपके पास वास्तव में 595,947 मिलान पंक्तियाँ हैं, जो आपके डेटा का लगभग 3% है। तो लुकअप की लागत जल्दी से बढ़ जाती है। मान लीजिए कि आपकी तालिका में प्रति पृष्ठ 100 पंक्तियाँ हैं, तो तालिका स्कैन में पढ़ने के लिए 200,000 पृष्ठ हैं। यह 595,947 लुक्स करने से काफी सस्ता है।

GROUP BYप्रश्न में खंड के साथ , मुझे लगता है कि आप एक समग्र कुंजी (माप, स्नैपशॉटके, मेजबांड) के साथ बेहतर होंगे।

"लापता सूचकांक" सुझाव को देखें। यह आपको लुकअप से बचने के लिए कॉलम शामिल करने के लिए कहता है। आम तौर पर, यदि आप अपनी क्वेरी में अन्य स्तंभों का संदर्भ देते हैं, तो उन्हें INCLUDEनए इंडेक्स की कुंजियों या खंड में होना चाहिए । अन्यथा उन मूल्यों को प्राप्त करने के लिए अभी भी 595,947 लुकअप करने की आवश्यकता होगी।

उदाहरण के लिए, क्वेरी के लिए:

select Measure, SnapshotKey, MeasureBand, SUM(NumLoans), SUM(PrinBal)
from t1
where Measure = 'FinanceFICOScore'
group by Measure, SnapshotKey, MeasureBand

... आपको इसकी आवश्यकता होगी:

CREATE INDEX ixWhatever 
ON t1 (Measure, SnapshotKey, MeasureBand) 
INCLUDE (NumLoans,PrinBal);

6
  1. आपके WHERE की स्थिति का क्षेत्र सूचकांक का प्रमुख क्षेत्र नहीं है।

  2. आपने measureNVARCHAR के रूप में परिभाषित किया है इसलिए एक के साथ शाब्दिक उपसर्ग N: a where Measure = N'FinanceFICOScore'

पर एक संकुल सूचकांक बनाने पर विचार करें SnapshotKey। यदि यह अद्वितीय है तो यह पीके (और क्लस्टर) हो सकता है। यदि अद्वितीय नहीं है, तो यह पीके नहीं हो सकता है, लेकिन फिर भी एक गैर-अद्वितीय क्लस्टर इंडेक्स हो सकता है। तब आपका नॉन-क्लस्टर्ड इंडेक्स केवल measureकॉलम पर होगा ।

और, यह देखते हुए कि पहला क्षेत्र GROUP BYभी है measure, यह भी measureअग्रणी क्षेत्र होने से लाभ होगा ।

वास्तव में, इस ऑपरेशन के लिए, आपको नॉन-क्लस्टर किए गए इंडेक्स को इसके बजाय Measure, SnapshotKey, MeasureBandउस सटीक क्रम में परिभाषित करना होगा , क्योंकि यह GROUP BYक्लॉज से मेल खाता है । आकार-वार जो केवल MeasureBandगैर-संकुल सूचकांक के बाद से वास्तव में जोड़ रहा है Measure, और MeasureKeyपहले से ही सूचकांक में शामिल है, क्योंकि यह अब क्लस्टर सूचकांक सूची (नहीं, Measureगैर-अनुक्रमित सूचकांक में नकल नहीं होगी)।

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


इस उत्तर पर चर्चा को चैट में स्थानांतरित कर दिया गया है ।
पॉल व्हाइट 9
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.