मुझे लगता है कि जब वहाँ अस्थायी घटनाओं (धीमी क्वेरी के कारण) है कि अक्सर पंक्ति अनुमान एक विशेष रूप से शामिल होने के लिए बंद हैं। मैंने देखा है कि स्पिल की घटनाएं मर्ज और हैश जॉइन के साथ होती हैं और वे अक्सर रनटाइम 3x को बढ़ाकर 10x कर देते हैं। यह सवाल चिंता का विषय है कि इस अनुमान के तहत पंक्ति अनुमानों को कैसे बेहतर बनाया जाए कि इससे स्पिल घटनाओं की संभावना कम हो जाए।
पंक्तियों की वास्तविक संख्या 40k।
इस क्वेरी के लिए, योजना खराब पंक्ति अनुमान (11.3 पंक्तियाँ) दिखाती है:
select Value
from Oav.ValueArray
where ObjectId = (select convert(bigint, Value) NodeId
from Oav.ValueArray
where PropertyId = 3331
and ObjectId = 3540233
and Sequence = 2)
and PropertyId = 2840
option (recompile);
इस प्रश्न के लिए, योजना अच्छी पंक्ति अनुमान (56k पंक्तियाँ) दिखाती है:
declare @a bigint = (select convert(bigint, Value) NodeId
from Oav.ValueArray
where PropertyId = 3331
and ObjectId = 3540233
and Sequence = 2);
select Value
from Oav.ValueArray
where ObjectId = @a
and PropertyId = 2840
option (recompile);
क्या पहले मामले के लिए पंक्ति अनुमानों को बेहतर बनाने के लिए आंकड़े या संकेत जोड़े जा सकते हैं? मैंने विशेष फ़िल्टर मानों (संपत्ति = 2840) के साथ आँकड़े जोड़ने की कोशिश की, लेकिन या तो संयोजन सही नहीं हो सका या शायद इसे अनदेखा किया जा रहा है क्योंकि ObjectId संकलन समय पर अज्ञात है और यह सभी ObjectIds पर औसत का चयन कर सकता है।
क्या कोई ऐसा मोड है जहां यह पहले जांच क्वेरी करता है और फिर पंक्ति अनुमानों का निर्धारण करने के लिए इसका उपयोग करता है या इसे नेत्रहीन उड़ना चाहिए?
इस विशेष संपत्ति में कुछ वस्तुओं पर कई मूल्य (40k) हैं और विशाल बहुमत पर शून्य है। मुझे एक संकेत से खुशी होगी जहां एक दिए गए जॉइन के लिए पंक्तियों की अधिकतम अपेक्षित संख्या निर्दिष्ट की जा सकती है। यह आम तौर पर परेशान करने वाली समस्या है क्योंकि कुछ मापदंडों को गतिशील रूप से जुड़ने के हिस्से के रूप में निर्धारित किया जा सकता है या एक दृश्य के भीतर रखा जाएगा (चर के लिए कोई समर्थन नहीं)।
क्या कोई पैरामीटर हैं जो टेम्पर्ड (जैसे प्रति मिनट मेमोरी प्रति मिनट) फैल की संभावना को कम करने के लिए समायोजित किया जा सकता है? रोबस्ट प्लान का अनुमान पर कोई प्रभाव नहीं पड़ा।
2013.11.06 को संपादित करें : टिप्पणियों का जवाब और अतिरिक्त जानकारी:
यहाँ क्वेरी प्लान इमेज हैं। चेतावनी कार्डिनलिटी के बारे में है / कन्वर्ट के साथ विधेय चाहते हैं ():
@Aaron बर्ट्रैंड की टिप्पणी के अनुसार, मैंने परीक्षण के रूप में कन्वर्ट () को बदलने की कोशिश की:
create table Oav.SeekObject (
LookupId bigint not null primary key,
ObjectId bigint not null
);
insert into Oav.SeekObject (
LookupId, ObjectId
) VALUES (
1, 3540233
)
select Value
from Oav.ValueArray
where ObjectId = (select ObjectId
from Oav.SeekObject
where LookupId = 1)
and PropertyId = 2840
option (recompile);
ब्याज के एक विषम लेकिन सफल बिंदु के रूप में, यह भी शॉर्ट सर्किट देखने की अनुमति देता है:
select Value
from Oav.ValueArray
where ObjectId = (select ObjectId
from Oav.ValueArray
where PropertyId = 2840
and ObjectId = 3540233
and Sequence = 2)
and PropertyId = 2840
option (recompile);
इन दोनों की सूची एक उचित कुंजी लुकअप है लेकिन केवल पहले वाले ObjectId के "आउटपुट" को सूचीबद्ध करते हैं। मुझे लगता है कि यह दर्शाता है कि दूसरा वास्तव में कम परिचालित है?
क्या कोई यह सत्यापित कर सकता है कि क्या एकल-पंक्ति जांच कभी पंक्ति अनुमानों की सहायता से की जाती है? यह केवल हिस्टोग्राम अनुमानों के लिए अनुकूलन को सीमित करने के लिए गलत लगता है जब एक एकल-पंक्ति पीके लुकअप हिस्टोग्राम में लुकअप की सटीकता में सुधार कर सकता है (विशेषकर यदि स्पिल क्षमता या इतिहास है)। जब एक वास्तविक क्वेरी में इनमें से 10 उप-जोड़ होते हैं, तो आदर्श रूप से वे समानांतर में हो रहे होंगे।
एक साइड नोट, चूंकि sql_variant अपने आधार प्रकार (SQL_VARIANT_PROPERTY = BaseType) को फ़ील्ड के भीतर संग्रहीत करता है, मैं एक कन्वर्ट () को लगभग इतना महंगा होने की उम्मीद करूंगा जब तक कि यह "सीधे" परिवर्तनीय (जैसे दशमलव के लिए स्ट्रिंग नहीं है) int या हो सकता है int to bigint)। चूँकि यह संकलन समय पर ज्ञात नहीं है, लेकिन उपयोगकर्ता द्वारा जाना जा सकता है, शायद sql_variants के लिए एक "AssumeType (प्रकार, ...)" फ़ंक्शन उन्हें अधिक पारदर्शी तरीके से व्यवहार करने की अनुमति देगा।
declare @a bigint =
आपके द्वारा किए गए क्वेरी को विभाजित करने से मुझे एक प्राकृतिक समाधान लगता है, यह अस्वीकार्य क्यों है?
CONVERT()
कॉलम में उपयोग करने के लिए मजबूर करता है और फिर उनसे जुड़ता है। यह निश्चित रूप से कुशल नहीं है ज्यादातर मामले हैं। इस विशेष में, इसे परिवर्तित करने के लिए केवल एक ही मूल्य है ताकि यह संभवत: एक मुद्दा न हो लेकिन आपके पास मेज पर क्या अनुक्रमित हैं? ईएवी डिज़ाइन आमतौर पर केवल उचित अनुक्रमण के साथ अच्छा प्रदर्शन करते हैं (जिसका अर्थ है आमतौर पर संकीर्ण तालिकाओं में बहुत सारे अनुक्रमित)।