क्या इस विभाजन के दृश्य में अप्रासंगिक तालिकाओं को खत्म करने के लिए ऑप्टिमाइज़र को मजबूर करना संभव है?


22

मैं बड़ी तालिकाओं के लिए अलग-अलग आर्किटेक्चर का परीक्षण कर रहा हूं और एक सुझाव जो मैंने देखा है वह एक विभाजन दृश्य का उपयोग करना है, जिससे एक बड़ी तालिका छोटे, "विभाजन" तालिकाओं की एक श्रृंखला में टूट गई है।

1 , 2 , 3 , 4

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

हालाँकि, यदि मैं आयाम के कुछ अन्य पहलू पर फ़िल्टर करता हूँ, तो आशावादी प्रत्येक बेस टेबल के PK / CI पर चाहता है।

यहाँ प्रश्न में प्रश्न हैं:

select 
    od.[Year], 
    AvgValue = avg(ObservationValue)
from dbo.v_Observation o 
join dbo.ObservationDates od
    on o.ObservationDateKey = od.DateKey
where o.ObservationDateKey >= 20000101
    and o.ObservationDateKey <= 20051231
group by od.[Year];

select 
    od.[Year], 
    AvgValue = avg(ObservationValue)
from dbo.v_Observation o 
join dbo.ObservationDates od
    on o.ObservationDateKey = od.DateKey
where od.DateKey >= 20000101
    and od.DateKey <= 20051231
group by od.[Year];

select 
    od.[Year], 
    AvgValue = avg(ObservationValue)
from dbo.v_Observation o 
join dbo.ObservationDates od
    on o.ObservationDateKey = od.DateKey
where od.[Year] >= 2000 and od.[Year] < 2006
group by od.[Year];

कुंजी पर तथ्य फ़िल्टर

कुंजी पर मंद फ़िल्टर

पहलू पर मंद फ़िल्टर

यहां SQL संतरी योजना एक्सप्लोरर सत्र का लिंक दिया गया है।

मैं वास्तव में बड़ी तालिका को विभाजित करने के लिए काम कर रहा हूं यह देखने के लिए कि क्या मुझे इसी तरह से जवाब देने के लिए विभाजन उन्मूलन मिलता है।

मुझे उस सरल (सरल) क्वेरी के लिए विभाजन उन्मूलन मिलता है जो आयाम के एक पहलू पर फ़िल्टर करता है।

इस बीच, यहाँ डेटाबेस की केवल एक प्रति है:

https://gist.github.com/swasheck/9a22bf8a580995d3b2aa

"पुराने" कार्डिनैलिटी अनुमानक को कम खर्चीली योजना मिलती है, लेकिन ऐसा इसलिए है क्योंकि (अनावश्यक) इंडेक्स में से प्रत्येक पर कार्डिनैलिटी का अनुमान कम है।

मैं जानना चाहता हूं कि क्या आयाम के किसी अन्य पहलू को फ़िल्टर करते समय कुंजी स्तंभ का उपयोग करने के लिए ऑप्टिमाइज़र प्राप्त करने का एक तरीका है ताकि यह अप्रासंगिक तालिकाओं पर खोज को समाप्त कर सके।

SQL सर्वर संस्करण:

Microsoft SQL Server 2014 - 12.0.2000.8 (X64) 
    Feb 20 2014 20:04:26 
    Copyright (c) Microsoft Corporation
    Developer Edition (64-bit) on Windows NT 6.3 <X64> (Build 9600: ) (Hypervisor)

बस एक FYI करें .. अंतिम स्टेट स्ट्रीम को दूषित कर दिया गया हैCREATE STATISTICS [_WA_Sys_00000008_2FCF1A8A] ON [dbo].[Observation_2010]([StationStateCode]) WITH STATS_STREAM = 0x01000000010000000000000000000000D4531EDB00000000D5080000000000009508000000000000AF030000AF000000020000000000000008D000340000000007000000E65DE0007DA5000076F9780000000000867704000000000000000000ABAAAA3C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
परिजन शाह

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

@GeoffPatterson यह मेरे लिए काम करता है। क्या आपने कच्ची फ़ाइल के लिंक पर क्लिक किया है? gist.githubusercontent.com/swasheck/9a22bf8a580995d3b2aa/raw/… हालाँकि, जैसा कि परिजन ने उल्लेख किया है, अंतिम आँकड़े स्ट्रीम दूषित है: /
swasheck

मैंने कच्ची फ़ाइल के लिंक पर क्लिक किया। स्क्रिप्ट काम करती है (समस्या नोट को छोड़कर), लेकिन आँकड़े बनाने के लिए कोई तर्क नहीं है ObservationDates। मैंने UPDATE STATISTICS ObservationDates WITH ROWCOUNT = 10000उस योजना को प्राप्त करने के लिए मैन्युअल रूप से चलना शुरू कर दिया , जिसे पॉल ने हालांकि प्रदर्शित किया।
ज्योफ पैटरसन

अजीब। एक नया डेटाबेस बनाने और उस स्क्रिप्ट को चलाने के लिए मेरे पास आँकड़े ऑब्जेक्ट्स हैं (ठीक है, वे अनुक्रमित हैं) ObservationDatesइसलिए मुझे यकीन नहीं है कि इसके साथ क्या हो रहा है। इसके अलावा, मैं या तो योजना बनाने में सक्षम नहीं हूं। मैं देखने के लिए अद्यतन का प्रयास करूँगा।
स्वैसेक

जवाबों:


10

ट्रेस ध्वज 4199 सक्षम करें।

मुझे भी जारी करना था:

UPDATE STATISTICS dbo.ObservationDates 
WITH ROWCOUNT = 73049;

नीचे दिखाए गए प्लान प्राप्त करने के लिए। इस तालिका के आंकड़े अपलोड से गायब थे। 73,049 का आंकड़ा योजना एक्सप्लोरर लगाव में टेबल कार्डिनैलिटी जानकारी से आया था। मैंने दो तार्किक प्रोसेसर के साथ SQL Server 2014 SP1 CU4 (12.0.4436 का निर्माण) का उपयोग किया, अधिकतम मेमोरी 2048 एमबी पर सेट की गई, और 4199 से अलग कोई ट्रेस ध्वज नहीं।

आपको तब एक निष्पादन योजना प्राप्त करनी चाहिए जो गतिशील विभाजन को समाप्त करती है:

select 
    od.[Year], 
    AvgValue = avg(ObservationValue)
from dbo.v_Observation o 
join dbo.ObservationDates od
    on o.ObservationDateKey = od.DateKey
where 
    od.[Year] >= 2000 and od.[Year] < 2006
group by 
    od.[Year]
option (querytraceon 4199);

योजना का टुकड़ा:

योजना का टुकड़ा

यह बदतर लग सकता है, लेकिन फ़िल्टर सभी स्टार्ट-अप फ़िल्टर हैं। एक उदाहरण विधेय है:

फ़िल्टर गुण

लूप के पुनरावृत्ति के अनुसार, स्टार्ट-अप विधेय का परीक्षण किया जाता है, और केवल अगर यह सच है तो इसे निष्पादित करने के नीचे क्लस्टर इंडेक्स सीक है। इसलिए, गतिशील विभाजन उन्मूलन।

यह शायद स्थैतिक उन्मूलन के रूप में काफी कुशल नहीं है , खासकर अगर योजना समानांतर है।

आपको एक ही योजना प्राप्त करने के लिए संकेत की तरह MAXDOP 1, FAST 1या FORCESEEKदृश्य पर प्रयास करने की आवश्यकता हो सकती है । विभाजन किए गए विचारों (जैसे विभाजन तालिकाओं) के साथ ऑप्टिमाइज़र लागत विकल्प मुश्किल हो सकते हैं।

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


एम्बेडेड USE PLANसंकेत के साथ प्रश्न : (gist.github.com के माध्यम से):


1
महान जानकारी, धन्यवाद पॉल! मैं अपना जवाब लिखने के बाद सोच रहा था कि SQL सर्वर इस प्रकार का उन्मूलन क्यों नहीं कर सकता है। यह पता चला है, मैं इसे पहले नहीं देखा था!
ज्योफ पैटर्सन

6

मेरा अवलोकन हमेशा यह रहा है कि आपको विभाजन तालिका में "तालिका उन्मूलन" प्राप्त करने के लिए क्वेरी में स्पष्ट रूप से विभाजन कॉलम के लिए मूल्य (या मानों की सीमा) निर्दिष्ट करना होगा। यह SQL Server 2014 के माध्यम से SQL Server 2000 से उत्पादन में विभाजित विचारों का उपयोग करने के अनुभव पर आधारित है।

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

ध्यान दें कि विभाजित तालिकाओं के लिए, हालांकि, इस प्रकार की तलाश (एक विशिष्ट विभाजन के लिए) समर्थित है।

यदि आप विभाजन किए गए विचारों का उपयोग करने पर तय किए जाते हैं, तो एक और विकल्प आपकी क्वेरी को कई प्रश्नों में विभाजित करने के लिए है, जैसे:

-- Gather than the min/max values for the partition column
DECLARE @minDateKey INT,
        @maxDateKey INT
SELECT @minDateKey = MIN(DateKey),
        @maxDateKey = MAX(DateKey)
FROM dbo.ObservationDates od
WHERE od.[Year] >= 2000 and od.[Year] < 2006

-- Since I have a stats-only copy of the database, simulate having run the query above
-- (You can comment this out since you have the actual data.)
SELECT @minDateKey = 20000101, @maxDateKey = 20051231

-- Adjust the query to use the min/max values of the partition column
-- rather than filtering on a different column in the dimension table
select 
    od.[Year], 
    AvgValue = avg(ObservationValue)
from dbo.v_Observation o 
join dbo.ObservationDates od
    on o.ObservationDateKey = od.DateKey
WHERE od.DateKey >= @minDateKey AND od.DateKey <= @maxDateKey
group by od.[Year]
-- Must use OPTION RECOMPILE; otherwise the plan will touch all tables because it
-- must do so in order to be valid for all values of the parameters!
OPTION (RECOMPILE)

इससे निम्न योजना तैयार होती है। अब एक अतिरिक्त क्वेरी है जो आयाम तालिका को हिट करती है, लेकिन वास्तव में (अधिक बड़ी) तथ्य तालिका के क्वेरी को अनुकूलित किया जाता है।

यहाँ छवि विवरण दर्ज करें


क्या आप वैसा ही प्रभाव प्राप्त कर पाएंगे, जैसे आपने पहली क्वेरी को दूसरे में बिना चरों के शामिल किया है?
एंड्री एम

@AndriyM यदि मैं आपको सही तरीके से समझ रहा हूं, तो इसका उत्तर नहीं है, समान प्रभाव प्राप्त नहीं किया जाएगा और यदि आप दो प्रश्नों को संयोजित करने का प्रयास करते हैं, तो क्वेरी प्लान पार्टीशन व्यू में सभी तालिकाओं को स्पर्श करेगा। यदि आप पहली क्वेरी निष्पादित करते हैं, तो मानों को पेस्ट करें 20000101और 20051231चर के बजाय (या अपने आवेदन में दो अलग-अलग प्रश्नों के माध्यम से ऐसा ही करें), तो हाँ, चर का उपयोग किए बिना एक ही प्रभाव प्राप्त होगा।
ज्योफ पैटरसन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.