निष्पादन योजना महंगी CONVERT_IMPLICIT ऑपरेशन दिखाती है। क्या मैं इसे इंडेक्सिंग के साथ ठीक कर सकता हूं या क्या मुझे टेबल बदलने की आवश्यकता है?


24

मेरे पास एक बहुत ही महत्वपूर्ण, वास्तव में धीमी गति से देखने वाला दृश्य है जिसमें इसके खंड में इस तरह की कुछ बहुत ही बदसूरत स्थितियां शामिल हैं। मुझे यह भी पता है कि varchar(13)पूर्णांक पहचान क्षेत्रों के बजाय जोड़ स्थूल और धीमी गति से जुड़ते हैं, लेकिन इस दृश्य का उपयोग करने वाले सरल क्वेरी को नीचे सुधारना चाहेंगे:

CREATE VIEW [dbo].[vwReallySlowView]  AS  
AS  
SELECT     
  I.booking_no_v32 AS bkno, 
  I.trans_type_v41 AS trantype, 
  B.Assigned_to_v61 AS Assignbk, 
  B.order_date AS dateo, B.HourBooked AS HBooked,   
  B.MinBooked AS MBooked, B.SecBooked AS SBooked, 
  I.prep_on AS Pon, I.From_locn AS Flocn, 
  I.Trans_to_locn AS TTlocn,   
                      (CASE I.prep_on WHEN 'Y' THEN I.PDate ELSE I.FirstDate END) AS PrDate, I.PTimeH AS PrTimeH, I.PTimeM AS PrTimeM,   
                      (CASE WHEN I.RetnDate < I.FirstDate THEN I.FirstDate ELSE I.RetnDate END) AS RDatev, I.bit_field_v41 AS bitField, I.FirstDate AS FDatev, I.BookDate AS DBooked,   
                      I.TimeBookedH AS TBookH, I.TimeBookedM AS TBookM, I.TimeBookedS AS TBookS, I.del_time_hour AS dth, I.del_time_min AS dtm, I.return_to_locn AS rtlocn,   
                      I.return_time_hour AS rth, I.return_time_min AS rtm, (CASE WHEN I.Trans_type_v41 IN (6, 7) AND (I.Trans_qty < I.QtyCheckedOut)   
                      THEN 0 WHEN I.Trans_type_v41 IN (6, 7) AND (I.Trans_qty >= I.QtyCheckedOut) THEN I.Trans_Qty - I.QtyCheckedOut ELSE I.trans_qty END) AS trqty,   
                      (CASE WHEN I.Trans_type_v41 IN (6, 7) THEN 0 ELSE I.QtyCheckedOut END) AS MyQtycheckedout, (CASE WHEN I.Trans_type_v41 IN (6, 7)   
                      THEN 0 ELSE I.QtyReturned END) AS retqty, I.ID, B.BookingProgressStatus AS bkProg, I.product_code_v42, I.return_to_locn, I.AssignTo, I.AssignType,   
                      I.QtyReserved, B.DeprepOn,  
        (CASE  B.DeprepOn       
        WHEN 1 THEN  B.DeprepDateTime     
        ELSE   I.RetnDate  
           END)  AS DeprepDateTime, I.InRack 
FROM         dbo.tblItemtran AS I 

INNER JOIN  -- booking_no = varchar(13)
         dbo.tblbookings AS B ON B.booking_no = I.booking_no_v32  --  string inner-join

INNER JOIN  -- product_code = varchar(13) 
        dbo.tblInvmas AS M ON I.product_code_v42 = M.product_code  --  string inner-join

WHERE     (I.trans_type_v41 NOT IN (2, 3, 7, 18, 19, 20, 21, 12, 13, 22)) AND (I.trans_type_v41 NOT IN (6, 7)) AND (I.bit_field_v41 & 4 = 0) OR  
                      (I.trans_type_v41 NOT IN (6, 7)) AND (I.bit_field_v41 & 4 = 0) AND (B.BookingProgressStatus = 1) OR  
                      (I.trans_type_v41 IN (6, 7)) AND (I.bit_field_v41 & 4 = 0) AND (I.QtyCheckedOut = 0) OR  
                      (I.trans_type_v41 IN (6, 7)) AND (I.bit_field_v41 & 4 = 0) AND (I.QtyCheckedOut > 0) AND (I.trans_qty - (I.QtyCheckedOut - I.QtyReturned) > 0)  

यह दृश्य आमतौर पर इस तरह से उपयोग किया जाता है:

select * from vwReallySlowView
where product_code_v42  = 'LIGHTBULB100W'  -- find "100 watt lightbulb" rows

जब मैं इसे चलाने मैं विधेय के साथ, इस कार्य योजना लागू करके आइटम बैच की कुल लागत का 20 से 80% की लागत प्राप्त CONVERT_IMPLICIT( .... &(4))दिखा रहा है कि वह इन कर में बहुत धीमी गति से हो रहा है bitwise boolean testsकी तरह (I.ibitfield & 4 = 0)

मैं एमएस एसक्यूएल में या डीबीए प्रकार के विशेषज्ञ के रूप में सामान्य रूप से काम नहीं कर रहा हूं क्योंकि मैं ज्यादातर समय गैर-एसक्यूएल सॉफ्टवेयर डेवलपर हूं। लेकिन मुझे संदेह है कि इस तरह के बिटवाइज़ संयोजन एक बुरा विचार हैं, और यह बेहतर होगा कि असतत बूलियन फ़ील्ड्स हों।

क्या मैं किसी भी तरह इस इंडेक्स को बेहतर बना सकता हूं, स्कीमा को बदलने के बिना इस दृश्य को बेहतर ढंग से संभालने के लिए (जो कि हजारों स्थानों पर पहले से ही उत्पादन में है) या क्या मुझे bit_field_v41इस समस्या को ठीक करने के लिए अंतर्निहित तालिका को बदलना होगा जिसमें कई बूलियन मान एक पूर्णांक में पैक किए गए हैं। ?

tblItemtranइस निष्पादन योजना में स्कैन किया जा रहा है, जिस पर मेरा क्लस्टर सूचकांक है:

-- goal:  speed up  select * from vwReallySlowView where productcode  = 'X'
CREATE CLUSTERED INDEX [idxtblItemTranProductCodeAndTransType] ON [dbo].[tblItemtran] 
(
    [product_code_v42] ASC,  -- varchar(13)
    [trans_type_v41] ASC     -- int
)WITH ( PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, 
        IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, 
        ALLOW_PAGE_LOCKS  = ON) 
ON [PRIMARY]

इस CONVERT_IMPLICITप्रेडिकेट पर 27% लागत के परिणामस्वरूप अन्य उत्पादों में से एक के लिए निष्पादन योजना है। अद्यतन ध्यान दें कि इस मामले में, मेरी सबसे खराब नोड अब "हैश मैच" एक पर है inner join, जो 34% की लागत है मेरा मानना है कि यह एक लागत मैं टाल नहीं सकते, जब तक कि मैं कर रहा से बचने सकता है तारों पर मिलती है जो मैं वर्तमान में नहीं कर सकते इससे छुटकारा पाएं। INNER JOINऊपर दिए गए दृश्य में दोनों ऑपरेशन varchar(13)खेतों पर हैं।

नीचे दाएं कोने में ज़ूम किया गया:

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

.Sqlplan के रूप में संपूर्ण निष्पादन योजना स्काईड्राइव पर उपलब्ध है। यह छवि केवल दृश्य अवलोकन है। छवि को स्वयं देखने के लिए यहां क्लिक करें

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

अद्यतन पूरे कार्य योजना लागू करके पोस्ट की। मुझे यह पता नहीं लग सकता है कि क्या product_codeमूल्य वैचारिक रूप से खराब था, लेकिन ऐसा करने का एक तरीका यह है कि आप select count(*) from viewएक ही उत्पाद करने के बजाय। लेकिन उत्पाद जो केवल अंतर्निहित तालिका में रिकॉर्ड के 5% में उपयोग किए जाते हैं या कम CONVERT_IMPLICIT ऑपरेशन में बहुत कम लागत दिखाते हैं । अगर मैं यहाँ एसक्यूएल को ठीक करने जा रहा था, मुझे लगता है कि मैं देखने में सकल WHEREखंड ले लूंगा , और उस विशालता के परिणाम की गणना और संग्रहित करूंगा, जहां-टेबल में अंतर्निहित तालिका में "सम्मिलित करें" दृश्य के रूप में खंड-स्थिति है। । प्रेस्टो, समस्या हल हो गई, है ना?



TheSQLPLAN मैंने पोस्ट किया है मूल छवि में 432k / 17k मामले की तुलना में बहुत कम पैथोलॉजिकल है। मैं क्षमा चाहता हूं product_codeकि मैं 87%अपने डेटा के साथ उस पैथोलॉजिकल मामले को उत्पन्न करने के लिए इस्तेमाल किया गया मूल्य नहीं पा सकता हूं। अब चित्र दिखाते हैं 27%। फिर से, मेरे संपादन के कारण भ्रम के लिए माफी।
वॉरेन पी

जवाबों:


49

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

आइटमट्रेन क्लस्टरड इंडेक्स सीक ऑपरेटर

आइटमट्रान क्लस्टर इंडेक्स सीक

यह ऑपरेटर वास्तव में एक में दो ऑपरेशन हैं। पहले एक इंडेक्स सीक ऑपरेशन सभी पंक्तियों को ढूंढता है जो विधेय से मेल खाती हैं product_code_v42 = 'M10BOLT', फिर प्रत्येक पंक्ति में अवशिष्ट विधेय bit_field_v41 & 4 = 0लागू होता है। bit_field_v41इसके आधार प्रकार ( tinyintया smallint) से लेकर इसमें तक का अंतर्निहित रूपांतरण है integer

रूपांतरण इसलिए होता है क्योंकि बिटवाइज़-एंड ऑपरेटर (&) दोनों ऑपरेंड को एक ही प्रकार का होना चाहिए। निरंतर मान '4' का निहितार्थ पूर्णांक है और डेटा प्रकार पूर्वता नियम का मतलब है कि निचली प्राथमिकता वाले bit_field_v41क्षेत्र का मान परिवर्तित होता है।

समस्या (जैसे कि यह है) को विधेय के रूप में लिखकर आसानी से ठीक किया जाता है bit_field_v41 & CONVERT(tinyint, 4) = 0- जिसका अर्थ है कि निरंतर मान की प्राथमिकता निम्न है और स्तंभ मान के बजाय परिवर्तित (निरंतर तह के दौरान) है। अगर bit_field_v41है tinyintबिना किसी रूपांतरण सब पर होते हैं। इसी तरह, CONVERT(smallint, 4)अगर इस्तेमाल किया जा सकता bit_field_v41है smallint। उस ने कहा, रूपांतरण इस मामले में एक प्रदर्शन मुद्दा नहीं है , लेकिन यह अभी भी प्रकार से मेल खाने और जहां संभव हो, निहितार्थ से बचने के लिए अच्छा अभ्यास है।

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

चाहने वाले, अवशिष्ट विधेय और आउटपुट कॉलम को देखते हुए, इस ऑपरेटर के प्रदर्शन को समतुल्य क्वेरी का निर्माण करके अलगाव में जाँच की जा सकती है (यह 1 <> 2ऑटो-पैरामीटर को रोकने के लिए एक चाल है, विरोधाभास को ऑप्टिमाइज़र द्वारा हटा दिया जाता है और दिखाई नहीं देता है) क्वेरी योजना):

SELECT
    it.booking_no_v32,
    it.QtyCheckedOut,
    it.QtyReturned,
    it.Trans_qty,
    it.trans_type_v41
FROM dbo.tblItemTran AS it
WHERE
    1 <> 2
    AND it.product_code_v42 = 'M10BOLT'
    AND it.bit_field_v41 & CONVERT(tinyint, 4) = 0;

एक ठंडे डेटा कैश के साथ इस क्वेरी का प्रदर्शन दिलचस्पी का है, क्योंकि तालिका से आगे पढ़ा प्रभावित होगा (क्लस्टर इंडेक्स) विखंडन। इस तालिका के लिए क्लस्टरिंग कुंजी विखंडन को आमंत्रित करती है, इसलिए नियमित रूप से इस सूचकांक को बनाए रखना (पुन: व्यवस्थित या पुनर्निर्माण) करना महत्वपूर्ण हो सकता है, और FILLFACTORसूचकांक रखरखाव खिड़कियों के बीच नई पंक्तियों के लिए जगह की अनुमति देने के लिए एक उपयुक्त का उपयोग करें ।

मैंने SQL डेटा जेनरेटर का उपयोग करके उत्पन्न नमूना डेटा का उपयोग करके रीड-फ़ॉरवर्ड पर विखंडन के प्रभाव का एक परीक्षण किया । प्रश्न की क्वेरी योजना में दिखाए गए समान तालिका पंक्ति गणना का उपयोग करते हुए, एक अत्यधिक खंडित क्लस्टर सूचकांक SELECT * FROM view15 सेकंड के बाद लिया जाता है DBCC DROPCLEANBUFFERS। 3 सेकंड में पूरा किए गए ItemTrans टेबल पर एक ताज़ा-पुनर्निर्मित क्लस्टर अनुक्रमणिका के साथ समान स्थितियों में समान परीक्षण।

यदि टेबल डेटा आमतौर पर पूरी तरह से कैश में है तो विखंडन समस्या बहुत कम महत्वपूर्ण है। लेकिन, कम विखंडन के साथ, विस्तृत तालिका पंक्तियों का मतलब हो सकता है कि तार्किक और भौतिक रीड की संख्या अपेक्षा से बहुत अधिक है। आप CONVERTमेरी अपेक्षा को मान्य करने के लिए स्पष्ट रूप से जोड़ने और हटाने के साथ प्रयोग कर सकते हैं कि एक सर्वोत्तम अभ्यास उल्लंघन के अलावा निहित रूपांतरण मुद्दा यहां महत्वपूर्ण नहीं है।

बिंदु से अधिक साधक ऑपरेटर छोड़ने वाली पंक्तियों की अनुमानित संख्या है। अनुकूलन-समय का अनुमान 165 पंक्तियों का है, लेकिन निष्पादन समय पर 4,226 का उत्पादन किया गया। मैं इस बिंदु पर बाद में लौटूंगा, लेकिन विसंगति का मुख्य कारण यह है कि अवशिष्ट विधेयकों (बिटवाइड-एंड को शामिल करना) की चयनात्मकता ऑप्टिमाइज़र को भविष्यवाणी करने के लिए बहुत कठिन है - वास्तव में यह अनुमान लगाने का संकल्प करता है।

फ़िल्टर ऑपरेटर

फ़िल्टर ऑपरेटर

मैं यहाँ पर पहले से बताए गए फ़िल्टर दिखा रहा हूँ कि दोनों NOT INसूचियों को कैसे संयोजित किया गया है, सरलीकृत किया गया है और फिर विस्तार किया गया है, और निम्नलिखित हैश मैच चर्चा के लिए एक संदर्भ प्रदान करने के लिए भी। इसके प्रभावों को शामिल करने और प्रदर्शन पर फ़िल्टर ऑपरेटर के प्रभाव को निर्धारित करने के लिए तलाश से परीक्षण क्वेरी का विस्तार किया जा सकता है:

SELECT
    it.booking_no_v32,
    it.trans_type_v41,
    it.Trans_qty,
    it.QtyReturned,
    it.QtyCheckedOut
FROM dbo.tblItemTran AS it
WHERE
    it.product_code_v42 = 'M10BOLT'
    AND it.bit_field_v41 & CONVERT(tinyint, 4) = 0
    AND
    (
        (
            it.trans_type_v41 NOT IN (2, 3, 6, 7, 18, 19, 20, 21, 12, 13, 22)
            AND it.trans_type_v41 NOT IN (6, 7)
        )
        OR
        (
            it.trans_type_v41 NOT IN (6, 7)
        )
        OR 
        (
            it.trans_type_v41 IN (6, 7)
            AND it.QtyCheckedOut = 0
        )
        OR 
        (
            it.trans_type_v41 IN (6, 7)
            AND it.QtyCheckedOut > 0
            AND it.trans_qty - (it.QtyCheckedOut - it.QtyReturned) > 0
        )
    );

योजना में गणना स्केलर ऑपरेटर निम्नलिखित अभिव्यक्ति को परिभाषित करता है (गणना बाद में ऑपरेटर द्वारा आवश्यक होने तक गणना खुद ही स्थगित कर दी जाती है):

[Expr1016] = (trans_qty - (QtyCheckedOut - QtyReturned))

हैश मैच संचालक

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

हैश मैच ऑपरेटर booking_no_v32, आइटमट्रेन तालिका से कॉलम (हैश कीज़ बिल्ड) के मूल्यों का उपयोग करके एक हैश टेबल बनाता है , और फिर booking_noबुकिंग टेबल से कॉलम (हैश कीज़ प्रोब) का उपयोग करके मैचों के लिए जांच करता है। SSMS टूलटिप भी आमतौर पर एक जांच अवशिष्ट दिखाएगा, लेकिन टूलटिप के लिए पाठ बहुत लंबा है और बस छोड़ा नहीं गया है।

सूचकांक की तलाश के बाद पहले देखे गए अवशेष के समान एक जांच अवशिष्ट है; अवशिष्ट विधेयकों का मूल्यांकन उन सभी पंक्तियों पर किया जाता है, जो यह निर्धारित करने के लिए हैश से मेल खाती हैं कि पंक्ति को मूल ऑपरेटर के पास जाना चाहिए या नहीं। एक अच्छी तरह से संतुलित हैश तालिका में हैश मैच ढूँढना बहुत तेज़ है, लेकिन प्रत्येक पंक्ति के लिए एक जटिल अवशिष्ट विधेय को लागू करना जो तुलना द्वारा काफी धीमा है। योजना एक्सप्लोरर में हैश मैच टूलटिप, जांच अवशिष्ट अभिव्यक्ति सहित विवरण दिखाता है:

हैश मैच संचालक

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

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

अफसोस की बात है कि SQL सर्वर 2012 से पहले, निष्पादन योजना में कोई संकेत नहीं है कि एक हैशिंग ऑपरेशन इसकी मेमोरी आवंटन से अधिक हो गया है (जो निष्पादन शुरू होने से पहले आरक्षित होने के बाद गतिशील रूप से नहीं बढ़ सकता है, भले ही सर्वर में मुफ्त मेमोरी का द्रव्यमान हो) और उसे फैल करना था tempdb। प्रोइलर का उपयोग करके हैश वार्निंग इवेंट क्लास की निगरानी करना संभव है , लेकिन किसी विशेष क्वेरी के साथ चेतावनियों को सहसंबंधित करना मुश्किल हो सकता है।

समस्याओं को ठीक करना

तीन मुद्दे विखंडन हैं, हैश मैच ऑपरेटर में जटिल जांच अवशिष्ट और सूचकांक की तलाश में अनुमान के परिणामस्वरूप गलत कार्डिनैलिटी का अनुमान है।

अनुशंसित समाधान

विखंडन की जाँच करें और यदि आवश्यक हो तो अनुक्रमणिका को सुनिश्चित करने के लिए अनुरक्षण रखरखाव को व्यवस्थित रूप से व्यवस्थित करने के लिए इसे ठीक करें। कार्डिनलिटी अनुमान को सही करने का सामान्य तरीका आंकड़े प्रदान करना है। इस मामले में, आशावादी को संयोजन ( product_code_v42, bitfield_v41 & 4 = 0) के लिए आंकड़े चाहिए । हम सीधे अभिव्यक्ति पर आँकड़े नहीं बना सकते हैं, इसलिए हमें पहले बिट फ़ील्ड अभिव्यक्ति के लिए एक गणना कॉलम बनाना होगा, और फिर मैन्युअल मल्टी-कॉलम आँकड़े बनाएँ:

ALTER TABLE dbo.tblItemTran
ADD Bit3 AS bit_field_v41 & CONVERT(tinyint, 4);

CREATE STATISTICS [stats dbo.ItemTran (product_code_v42, Bit3)]
ON dbo.tblItemTran (product_code_v42, Bit3);

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

मल्टी-कॉलम के आँकड़ों के परिणामस्वरूप बहुत बेहतर अनुमान लगाए गए, जिससे यह संभावना कम हो गई कि हैश मैच ऑपरेटर पुनरावर्ती स्पिलिंग या बेलआउट एल्गोरिथम का उपयोग करेगा। गणना किए गए कॉलम को जोड़ना (जो एक मेटाडेटा-केवल ऑपरेशन है, और तालिका में कोई स्थान नहीं लेता है क्योंकि यह चिह्नित नहीं है PERSISTED) और पहले कॉलम में मल्टी-कॉलम आँकड़े मेरा सबसे अच्छा अनुमान है।

क्वेरी प्रदर्शन समस्याओं को हल करते समय, बीता हुआ समय, सीपीयू उपयोग, तार्किक रीड, भौतिक रीड, प्रतीक्षा प्रकार और अवधि ... जैसी चीजों को मापना महत्वपूर्ण है। ऊपर दिखाए गए अनुसार संदिग्ध कारणों को मान्य करने के लिए क्वेरी के कुछ हिस्सों को अलग से चलाने के लिए भी यह उपयोगी हो सकता है।

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

अनुक्रमण देखें

सीधे मूल दृश्य को अनुक्रमित करने के लिए परीक्षा न करें। पढ़ें प्रदर्शन आश्चर्यजनक रूप से तेज़ होगा (एक दृश्य सूचकांक पर एक एकल) लेकिन (इस मामले में) मौजूदा क्वेरी योजनाओं में सभी प्रदर्शन समस्याओं को प्रश्नों में स्थानांतरित किया जाएगा जो दृश्य में संदर्भित किसी भी तालिका स्तंभ को संशोधित करते हैं। आधार तालिका पंक्तियों को बदलने वाली क्वेरी वास्तव में बहुत बुरी तरह से प्रभावित होंगी।

आंशिक अनुक्रमित दृश्य के साथ उन्नत समाधान

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

-- Indexed view to optimize the main view
CREATE VIEW dbo.V1
WITH SCHEMABINDING
AS
SELECT
    it.ID,
    it.product_code_v42,
    it.trans_type_v41,
    it.booking_no_v32,
    it.Trans_qty,
    it.QtyReturned,
    it.QtyCheckedOut,
    it.QtyReserved,
    it.bit_field_v41,
    it.prep_on,
    it.From_locn,
    it.Trans_to_locn,
    it.PDate,
    it.FirstDate,
    it.PTimeH,
    it.PTimeM,
    it.RetnDate,
    it.BookDate,
    it.TimeBookedH,
    it.TimeBookedM,
    it.TimeBookedS,
    it.del_time_hour,
    it.del_time_min,
    it.return_to_locn,
    it.return_time_hour,
    it.return_time_min,
    it.AssignTo,
    it.AssignType,
    it.InRack
FROM dbo.tblItemTran AS it
JOIN dbo.tblBookings AS tb ON
    tb.booking_no = it.booking_no_v32
WHERE
    (
        it.trans_type_v41 NOT IN (2, 3, 7, 18, 19, 20, 21, 12, 13, 22)
        AND it.trans_type_v41 NOT IN (6, 7)
        AND it.bit_field_v41 & CONVERT(tinyint, 4) = 0
    )
    OR
    (
        it.trans_type_v41 NOT IN (6, 7)
        AND it.bit_field_v41 & CONVERT(tinyint, 4) = 0
        AND tb.BookingProgressStatus = 1
    )
    OR 
    (
        it.trans_type_v41 IN (6, 7)
        AND it.bit_field_v41 & CONVERT(tinyint, 4) = 0
        AND it.QtyCheckedOut = 0
    )
    OR 
    (
        it.trans_type_v41 IN (6, 7)
        AND it.bit_field_v41 & CONVERT(tinyint, 4) = 0
        AND it.QtyCheckedOut > 0
        AND it.trans_qty - (it.QtyCheckedOut - it.QtyReturned) > 0
    );
GO
CREATE UNIQUE CLUSTERED INDEX cuq ON dbo.V1 (product_code_v42, ID);
GO

मौजूदा दृश्य ऊपर अनुक्रमित दृश्य का उपयोग करने के लिए tweaked:

CREATE VIEW [dbo].[vwReallySlowView2]
AS
SELECT
    I.booking_no_v32 AS bkno,
    I.trans_type_v41 AS trantype,
    B.Assigned_to_v61 AS Assignbk,
    B.order_date AS dateo,
    B.HourBooked AS HBooked,
    B.MinBooked AS MBooked,
    B.SecBooked AS SBooked,
    I.prep_on AS Pon,
    I.From_locn AS Flocn,
    I.Trans_to_locn AS TTlocn,
    CASE I.prep_on 
        WHEN 'Y' THEN I.PDate
        ELSE I.FirstDate
    END AS PrDate,
    I.PTimeH AS PrTimeH,
    I.PTimeM AS PrTimeM,
    CASE
        WHEN I.RetnDate < I.FirstDate 
        THEN I.FirstDate 
        ELSE I.RetnDate
    END AS RDatev,
    I.bit_field_v41 AS bitField,
    I.FirstDate AS FDatev,
    I.BookDate AS DBooked,
    I.TimeBookedH AS TBookH,
    I.TimeBookedM AS TBookM,
    I.TimeBookedS AS TBookS,
    I.del_time_hour AS dth,
    I.del_time_min AS dtm,
    I.return_to_locn AS rtlocn,
    I.return_time_hour AS rth,
    I.return_time_min AS rtm,
    CASE
        WHEN
            I.Trans_type_v41 IN (6, 7) 
            AND I.Trans_qty < I.QtyCheckedOut
            THEN 0 
        WHEN
            I.Trans_type_v41 IN (6, 7)
            AND I.Trans_qty >= I.QtyCheckedOut
            THEN I.Trans_Qty - I.QtyCheckedOut
        ELSE
            I.trans_qty
    END AS trqty,
    CASE
        WHEN I.Trans_type_v41 IN (6, 7)
        THEN 0
        ELSE I.QtyCheckedOut
    END AS MyQtycheckedout,
    CASE
        WHEN I.Trans_type_v41 IN (6, 7)
        THEN 0
        ELSE I.QtyReturned
    END AS retqty,
    I.ID,
    B.BookingProgressStatus AS bkProg,
    I.product_code_v42,
    I.return_to_locn,
    I.AssignTo,
    I.AssignType,
    I.QtyReserved,
    B.DeprepOn,
    CASE B.DeprepOn
        WHEN 1 THEN B.DeprepDateTime
        ELSE I.RetnDate
    END AS DeprepDateTime,
    I.InRack
FROM dbo.V1 AS I WITH (NOEXPAND)
JOIN dbo.tblbookings AS B ON
    B.booking_no = I.booking_no_v32
JOIN dbo.tblInvmas AS M ON
    I.product_code_v42 = M.product_code;

उदाहरण क्वेरी और निष्पादन योजना:

SELECT
    vrsv.*
FROM dbo.vwReallySlowView2 AS vrsv
WHERE vrsv.product_code_v42 = 'M10BOLT';

नई निष्पादन योजना

नई योजना में, हैश मैच है कोई अवशिष्ट विधेय , वहाँ है कोई जटिल फिल्टर , कोई अवशिष्ट विधेय अनुक्रमित दृश्य की तलाश पर है, और प्रमुखता अनुमान बिल्कुल सही हैं।

एक उदाहरण के रूप में कि कैसे सम्मिलित करें / अपडेट करें / हटाएं योजनाएं प्रभावित होंगी, यह आइटमट्रेन तालिका में सम्मिलित करने की योजना है:

योजना डालें

अनुक्रमित दृश्य रखरखाव के लिए हाइलाइट किया गया अनुभाग नया और आवश्यक है। टेबल स्पूल रिप्ले इंडेक्सेड व्यू मेंटेनेंस के लिए बेस टेबल रो को सम्मिलित करता है। प्रत्येक पंक्ति बुकिंग इंडेक्स की तलाश में बुकिंग टेबल में शामिल हो जाती है, फिर एक फ़िल्टर लागू होता है कि WHEREयह देखने के लिए कि क्या पंक्ति को देखने की जरूरत है, यह देखने के लिए जटिल क्लॉज लागू होता है । यदि ऐसा है, तो व्यू के क्लस्टर इंडेक्स में एक इंसर्ट किया जाता है।

एक ही SELECT * FROM viewपरीक्षण पहले 150 मीटर में जगह में अनुक्रमित दृश्य के साथ पूरा किया।

अंतिम बात: मैं नोटिस करता हूं कि आपका 2008 R2 सर्वर अभी भी RTM पर है। यह आपकी प्रदर्शन समस्याओं को ठीक नहीं करेगा, लेकिन 2008 R2 के लिए सर्विस पैक 2 जुलाई 2012 से उपलब्ध है, और सर्विस पैक के साथ वर्तमान को चालू रखने के लिए कई अच्छे कारण हैं।

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