2010-12-16 11 views
25

मेरे पास एक दृश्य है जो एक सीटीई का उपयोग कर तालिका से 2 इन्स लौटाता है। अगर मैं एक दूसरेएसक्यूएल सर्वर क्वेरी: परिवर्तनीय के साथ तेज़ लेकिन परिवर्तनीय

SELECT * FROM view1 WHERE ID = 1 

से कम इस तरह दृश्य उस में चलाता है क्वेरी लेकिन अगर मैं इस तरह दृश्य क्वेरी यह 4 सेकंड लेता है।

DECLARE @id INT = 1 
SELECT * FROM View1 WHERE ID = @id 

2 क्वेरी योजनाओं जांच की है और पहली क्वेरी एक क्लस्टर सूचकांक 1 रिकॉर्ड लौटने तो है कि परिणाम सेट, करने के लिए दृश्य क्वेरी का शेष भाग को लागू करने के मुख्य मेज पर तलाश प्रदर्शन कर रहा है, जहां दूसरे प्रश्न के रूप में एक इंडेक्स स्कैन कर रहा है जो कि मुझे दिलचस्पी रखने के बजाय 3000 परिणाम रिकॉर्ड रिकॉर्ड कर रहा है और बाद में परिणाम सेट को फ़िल्टर कर रहा है।

क्या कुछ स्पष्ट है कि मैं इंडेक्स स्कैन के बजाय इंडेक्स सीक का उपयोग करने के लिए दूसरी क्वेरी प्राप्त करने का प्रयास करने के लिए याद कर रहा हूं। मैं एसक्यूएल 2008 का उपयोग कर रहा हूं लेकिन मुझे जो कुछ भी करने की ज़रूरत है वह एसक्यूएल 2005 पर भी चलने की जरूरत है। सबसे पहले मैंने सोचा कि यह कुछ प्रकार का पैरामीटर स्नीफिंग समस्या है, लेकिन अगर मैं कैश साफ़ करता हूं तो भी मुझे वही परिणाम मिलते हैं।

+0

क्या डेटाटाइप आईडी है? – gbn

+0

यह एक आईएनटी फ़ील्ड है – Gavin

उत्तर

27

शायद ऐसा इसलिए है क्योंकि पैरामीटर मामले में, अनुकूलक पता नहीं कर सकते हैं कि मान शून्य नहीं है, इसलिए यह एक योजना है कि सही परिणाम तब भी जब यह है देता है बनाने के लिए की जरूरत है। यदि आपके पास SQL ​​Server 2008 SP1 है तो आप क्वेरी में OPTION(RECOMPILE) जोड़ने का प्रयास कर सकते हैं।

+2

+1 यहां एक चैंप की तरह काम करता है (और विभिन्न जॉइन/प्लान इत्यादि को मजबूर करने की कोशिश करने से बहुत कम मैनुअल) –

+1

@pst - यह सही सुझाव है लेकिन गलत तर्क है। ओपी में चर चरम नहीं है। और मुद्दा चुनिंदाता अनुमान है क्योंकि SQL सर्वर परिवर्तनीय स्नीफिंग नहीं करता है। नहीं "एक योजना बनाना जो 'न्यूल' से संबंधित है" –

+0

@ मार्टिनस्मिथ मुझे बचने वाले सभी छोटे विवरण :(मुझे पता है कि SQL सर्वर खुशी से 2 सेकंड (एसएमएसएस क्वेरी में) को एक I'm-gonna- एक टाइप किए गए डेटासेट के हिस्से के रूप में 10 मिनट के बाद एक एसक्यूएल कॉमांड (प्लेसहोल्डर्स के साथ) को रोकें। मैंने विकल्प (रिकॉम्प्ली) 'मार्ग का प्रयास करने से पहले संबंधित तालिकाओं पर सभी आंकड़े (बिना किसी विकल्प के) अपडेट किए हैं, लेकिन वह इस मुद्दे को ठीक नहीं लग रहा था। "एनएलएल से संबंधित एक योजना बनाने" का क्या अर्थ है? –

2

आप अपनी क्वेरी में hint के लिए एक विकल्प जोड़ सकते हैं, उदा।

DECLARE @id INT = 1 
SELECT * FROM View1 WHERE ID = @id OPTION (OPTIMIZE FOR (@ID = 1)) 
1

जब एसक्यूएल चर के साथ क्वेरी के लिए क्वेरी प्लान को अनुकूलित करना शुरू करता है तो यह कॉलम के खिलाफ उपलब्ध इंडेक्स से मेल खाता है। इस मामले में एक सूचकांक था इसलिए एसक्यूएल ने सोचा कि यह केवल मूल्य की तलाश में इंडेक्स को स्कैन करेगा। जब एसक्यूएल ने कॉलम के साथ क्वेरी के लिए योजना बनाई और एक शाब्दिक मूल्य यह आंकड़ों और मूल्य को देख सकता है कि यह तय करने के लिए कि क्या उसे इंडेक्स स्कैन करना चाहिए या यदि कोई खोज सही होगी।

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

0

इस मुद्दे पर खुद को आया और यह एक लापता सूचकांक के रूप में एक उपरोक्त के परिणामस्वरूप एक (बाएं) शामिल हो गया। के लिए bar.x

2

डीबी तालिका स्तंभ प्रकार में मेरे मामले में

select * 
from foo A 
left outer join (
    select x, count(*) 
    from bar 
    group by x 
) B on A.x = B.x 

जोड़ा एक सूचकांक नामित bar_x VARCHAR के रूप में और पैरामिट्रीकृत क्वेरी पैरामीटर प्रकार में NVARCHAR के रूप में परिभाषित किया गया था परिभाषित किया गया था, इस वास्तविक निष्पादन में CONVERT_IMPLICIT शुरू की तुलना करने से पहले डेटा प्रकार से मिलान करने की योजना है और वह बो प्रदर्शन के लिए अपराधी था, 2 सेकंड बनाम 11 सेकंड। पैरामीटर प्रकार को बस पैरामीटरयुक्त क्वेरी को यथासंभव तेज़ पैरामीटर वाले संस्करण के रूप में सही किया गया है।

आशा है कि यह किसी भी मुद्दे के साथ किसी की मदद कर सकता है।

0

मैं एक राय यह है कि एक सीधा काम के साथ < 10ms भाग गया साथ अपने आप को इस समस्या का सामना किया (कहां UtilAcctId = 12345), लेकिन 100 से अधिक बार जब तक एक चर काम के साथ लिया (कहां UtilAcctId = @UtilAcctId) ।
उत्तरार्द्ध के लिए निष्पादन-योजना अलग-अलग तालिका पर दृश्य चलाने के अलावा अलग नहीं थी।

मेरे समाधान में इंडेक्स, ऑप्टिमाइज़र-संकेत, या एक लंबे आंकड़े-अपडेट की आवश्यकता नहीं थी।

इसके बजाय मैं एक उपयोगकर्ता-तालिका-समारोह जहां पैरामीटर कहां खंड पर जरूरत मूल्य था में दृश्य बदल दिया। असल में यह WHERE क्लॉज 3 प्रश्नों को गहरा कर दिया गया था और यह अभी भी काम करता था और यह < 10ms की गति पर वापस आ गया था।

आखिरकार मैंने पैरामीटर को एक प्रकार के रूप में बदल दिया जो UtilAcctIds (int) की एक तालिका है। फिर मैं तालिका से किसी सूची में WHERE क्लॉज को सीमित कर सकता हूं। जहां UtilAcctId = [पैरामीटर-सूची] .UtilAcctId। यह भी बेहतर काम करता है। मुझे लगता है कि उपयोगकर्ता-टेबल-फ़ंक्शंस पूर्व-संकलित हैं।

संबंधित मुद्दे