Database
 sql >> डेटाबेस >  >> RDS >> Database

3 खराब I/O आँकड़े जो SQL क्वेरी प्रदर्शन को पीछे छोड़ते हैं

"लेकिन यह हमारे विकास सर्वर पर ठीक चला!"

SQL क्वेरी प्रदर्शन समस्याएँ यहाँ और वहाँ होने पर मैंने इसे कितनी बार सुना? मैंने इसे खुद दिन में वापस कहा था। मैंने माना कि एक सेकंड से भी कम समय में चलने वाली क्वेरी उत्पादन सर्वर में ठीक चलेगी। लेकिन मैं गलत था।

क्या आप इस अनुभव से संबंधित हो सकते हैं? अगर आप आज भी किसी कारणवश इस नाव में हैं तो यह पोस्ट आपके लिए है। यह आपको अपने SQL क्वेरी प्रदर्शन को बेहतर बनाने का एक बेहतर मीट्रिक देगा। हम सांख्यिकी IO में तीन सबसे महत्वपूर्ण आंकड़ों के बारे में बात करेंगे।

उदाहरण के तौर पर, हम एडवेंचरवर्क्स नमूना डेटाबेस का उपयोग करेंगे।

इससे पहले कि आप नीचे क्वेरी चलाना शुरू करें, सांख्यिकी IO चालू करें। इसे क्वेरी विंडो में कैसे करें:

USE AdventureWorks
GO

SET STATISTICS IO ON

एक बार जब आप STATISTICS IO ON के साथ कोई क्वेरी चलाते हैं, तो अलग-अलग संदेश दिखाई देंगे। आप इन्हें SQL सर्वर प्रबंधन स्टूडियो में क्वेरी विंडो के संदेश टैब में देख सकते हैं (चित्र 1 देखें):

अब जब हमने संक्षिप्त परिचय का काम पूरा कर लिया है तो आइए गहराई से देखें।

1. उच्च तार्किक पढ़ता है

हमारी सूची में पहला बिंदु सबसे आम अपराधी है - उच्च तार्किक पढ़ता है।

तार्किक पठन डेटा कैश से पढ़े जाने वाले पृष्ठों की संख्या है। एक पेज का साइज 8KB है। दूसरी ओर, डेटा कैश, SQL सर्वर द्वारा उपयोग की जाने वाली RAM को संदर्भित करता है।

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

लेकिन बीता हुआ समय के बजाय तार्किक पठन का उपयोग क्यों करें?

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

बीते हुए समय पर भरोसा करने से आप कहेंगे, "लेकिन यह हमारे विकास सर्वर में ठीक चला!" जल्दी या बाद में।

भौतिक पठन के बजाय तार्किक पठन का उपयोग क्यों करें?

  • भौतिक रीड डिस्क से डेटा कैश (मेमोरी में) में पढ़े जाने वाले पृष्ठों की संख्या है। एक बार क्वेरी में आवश्यक पृष्ठ डेटा कैश में हो जाने के बाद, उन्हें डिस्क से फिर से पढ़ने की कोई आवश्यकता नहीं है।
  • जब वही क्वेरी फिर से चलाई जाती है, तो भौतिक पठन शून्य हो जाएगा।

SQL क्वेरी प्रदर्शन को फ़ाइन-ट्यूनिंग करने के लिए लॉजिकल रीड तार्किक विकल्प हैं।

इसे क्रिया में देखने के लिए, एक उदाहरण पर चलते हैं।

तार्किक पठन का उदाहरण

मान लीजिए कि आपको पिछले 11 जुलाई, 2011 को शिप किए गए ऑर्डर वाले ग्राहकों की सूची प्राप्त करने की आवश्यकता है। आप इसे बहुत ही सरल क्वेरी के साथ लेकर आते हैं:

SELECT
 d.FirstName
,d.MiddleName
,d.LastName
,d.Suffix
,a.OrderDate
,a.ShipDate
,a.Status
,b.ProductID
,b.OrderQty
,b.UnitPrice
FROM Sales.SalesOrderHeader a
INNER JOIN Sales.SalesOrderDetail b ON a.SalesOrderID = b.SalesOrderID
INNER JOIN Sales.Customer c ON a.CustomerID = c.CustomerID
INNER JOIN Person.Person d ON c.PersonID = D.BusinessEntityID
WHERE a.ShipDate = '07/11/2011'

यह सीधा है। इस क्वेरी का निम्न आउटपुट होगा:

फिर, आप इस क्वेरी के सांख्यिकी IO परिणाम की जाँच करें:

आउटपुट क्वेरी में प्रयुक्त चार तालिकाओं में से प्रत्येक के तार्किक पठन को दिखाता है। कुल मिलाकर, तार्किक पठन का योग 729 है। आप 21 के कुल योग के साथ भौतिक पठन भी देख सकते हैं। हालाँकि, लेकिन क्वेरी को फिर से चलाने का प्रयास करें, और यह शून्य हो जाएगा।

SalesOrderHeader . के तार्किक पठन पर करीब से नज़र डालें . क्या आपको आश्चर्य है कि इसमें 689 तार्किक पठन क्यों हैं? शायद, आपने नीचे दी गई क्वेरी की निष्पादन योजना का निरीक्षण करने के बारे में सोचा:

एक बात के लिए, एक इंडेक्स स्कैन है जो SalesOrderHeader में हुआ है 93% लागत के साथ। क्या हो सकता है? मान लें कि आपने इसके गुणों की जाँच कर ली है:

वाह! 31,465 पंक्तियाँ केवल 5 पंक्तियों के लिए पढ़ी गईं? यह बेतुका है!

तार्किक पढ़ने की संख्या कम करना

पढ़ी गई 31,465 पंक्तियों को कम करना इतना कठिन नहीं है। SQL सर्वर ने हमें पहले ही एक सुराग दिया है। निम्नलिखित के लिए आगे बढ़ें:

चरण 1:SQL सर्वर की अनुशंसा का पालन करें और अनुपलब्ध अनुक्रमणिका जोड़ें

क्या आपने निष्पादन योजना (चित्र 4) में अनुपलब्ध सूचकांक अनुशंसा पर ध्यान दिया? क्या इससे समस्या ठीक हो जाएगी?

इसका पता लगाने का एक तरीका है:

CREATE NONCLUSTERED INDEX [IX_SalesOrderHeader_ShipDate]
ON [Sales].[SalesOrderHeader] ([ShipDate])

क्वेरी को फिर से चलाएँ और STATISTICS IO लॉजिकल रीड्स में परिवर्तन देखें।

जैसा कि आप सांख्यिकी IO (चित्र 6) में देख सकते हैं, तार्किक पठन में 689 से 17 तक भारी कमी आई है। नए समग्र तार्किक पठन 57 हैं, जो 729 तार्किक पठन से एक महत्वपूर्ण सुधार है। लेकिन यह सुनिश्चित करने के लिए, निष्पादन योजना का फिर से निरीक्षण करें।

ऐसा लगता है कि योजना में सुधार हुआ है जिसके परिणामस्वरूप तार्किक पठन कम हो गया है। इंडेक्स स्कैन अब इंडेक्स की तलाश है। SQL सर्वर को अब Shipdate='07/11/2011′ के साथ रिकॉर्ड प्राप्त करने के लिए पंक्ति-दर-पंक्ति का निरीक्षण करने की आवश्यकता नहीं होगी . लेकिन उस योजना में अभी भी कुछ छिपा है, और यह सही नहीं है।

आपको चरण 2 की आवश्यकता है।

चरण 2:अनुक्रमणिका बदलें और शामिल कॉलम में जोड़ें:ऑर्डर दिनांक, स्थिति और ग्राहक आईडी

क्या आप निष्पादन योजना (चित्र 7) में उस कुंजी लुकअप ऑपरेटर को देखते हैं? इसका मतलब है कि बनाया गया गैर-संकुल सूचकांक पर्याप्त नहीं है - क्वेरी प्रोसेसर को फिर से संकुल सूचकांक का उपयोग करने की आवश्यकता है।

आइए इसके गुणों की जाँच करें।

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

हमें उस की लुकअप को हटाना होगा। समाधान आदेश दिनांक . को शामिल करना है , स्थिति , और ग्राहक आईडी पहले बनाए गए इंडेक्स में कॉलम।

  • IX_SalesOrderHeader_ShipDate पर राइट-क्लिक करें एसएसएमएस में।
  • चुनें गुण
  • शामिल कॉलम पर क्लिक करें टैब।
  • आदेश दिनांकजोड़ें , स्थिति , और ग्राहक आईडी
  • ठीकक्लिक करें ।

अनुक्रमणिका को फिर से बनाने के बाद, क्वेरी को फिर से चलाएँ। क्या यह कुंजी लुकअप को हटा देगा और तार्किक पठन कम करें?

वो कर गया काम! 17 तार्किक पठन से 2 तक (चित्र 9)।

और कुंजी लुकअप ?

वह चला गया! संकुल अनुक्रमणिका खोज की लुकअप को बदल दिया है।

द टेकअवे

तो, हमने क्या सीखा?

तार्किक पठन को कम करने और SQL क्वेरी प्रदर्शन में सुधार करने के प्राथमिक तरीकों में से एक उपयुक्त अनुक्रमणिका बनाना है। लेकिन एक पकड़ है। हमारे उदाहरण में, इसने तार्किक पठन को कम कर दिया। कभी-कभी, विपरीत सही होगा। यह अन्य संबंधित प्रश्नों के प्रदर्शन को भी प्रभावित कर सकता है।

इसलिए, इंडेक्स बनाने के बाद हमेशा सांख्यिकी आईओ और निष्पादन योजना की जांच करें।

2. हाई लोब लॉजिकल रीड्स

यह बिंदु #1 के समान ही है, लेकिन यह डेटा प्रकार पाठ . से निपटेगा , ntext , छवि , वर्कर (अधिकतम ), नवरचर (अधिकतम ), वरबाइनरी (अधिकतम ), या कॉलमस्टोर अनुक्रमणिका पृष्ठ।

आइए एक उदाहरण देखें:लोब लॉजिकल रीड जनरेट करना।

लॉब लॉजिकल रीड्स का उदाहरण

मान लें कि आप किसी उत्पाद को उसकी कीमत, रंग, थंबनेल छवि और वेब पेज पर एक बड़ी छवि के साथ प्रदर्शित करना चाहते हैं। इस प्रकार, आप एक प्रारंभिक क्वेरी के साथ आते हैं जैसा कि नीचे दिखाया गया है:

SELECT
 a.ProductID
,a.Name AS ProductName
,a.ListPrice
,a.Color
,b.Name AS ProductSubcategory
,d.ThumbNailPhoto
,d.LargePhoto
FROM Production.Product a
INNER JOIN Production.ProductSubcategory b ON a.ProductSubcategoryID = b.ProductSubcategoryID
INNER JOIN Production.ProductProductPhoto c ON a.ProductID = c.ProductID
INNER JOIN Production.ProductPhoto d ON c.ProductPhotoID = d.ProductPhotoID
WHERE b.ProductCategoryID = 1 -- Bikes
ORDER BY ProductSubcategory, ProductName, a.Color

फिर, आप इसे चलाते हैं और नीचे दिए गए आउटपुट की तरह देखते हैं:

चूंकि आप इतने उच्च-प्रदर्शन-दिमाग वाले व्यक्ति (या लड़की) हैं, आप तुरंत सांख्यिकी आईओ की जांच करते हैं। यहाँ यह है:

ऐसा लगता है जैसे आपकी आंखों में कुछ गंदगी है। 665 लॉब तार्किक पढ़ता है? आप इसे स्वीकार नहीं कर सकते। उल्लेख नहीं है कि ProductPhoto . से प्रत्येक में 194 तार्किक पठन हैं और ProductProductPhoto टेबल। आपको वाकई लगता है कि इस क्वेरी में कुछ बदलाव की ज़रूरत है।

लॉब तार्किक पठन को कम करना

पिछली क्वेरी में 97 पंक्तियाँ वापस आ गई थीं। सभी 97 बाइक। क्या आपको लगता है कि इसे वेब पेज पर प्रदर्शित करना अच्छा है?

एक अनुक्रमणिका मदद कर सकती है, लेकिन पहले क्वेरी को सरल क्यों न करें? इस तरह, आप चयनात्मक हो सकते हैं कि SQL सर्वर क्या लौटाएगा। आप लोब तार्किक पठन को कम कर सकते हैं।

  • उत्पाद उपश्रेणी के लिए एक फ़िल्टर जोड़ें और ग्राहक को चुनने दें। फिर इसे WHERE क्लॉज में शामिल करें।
  • उत्पाद उपश्रेणी निकालें कॉलम क्योंकि आप उत्पाद उपश्रेणी के लिए एक फ़िल्टर जोड़ेंगे।
  • बड़ी तस्वीर निकालें कॉलम। जब उपयोगकर्ता किसी विशिष्ट उत्पाद का चयन करता है तो इसे क्वेरी करें।
  • पेजिंग का प्रयोग करें। ग्राहक एक बार में सभी 97 बाइक नहीं देख पाएगा।

ऊपर वर्णित इन कार्यों के आधार पर, हम क्वेरी को इस प्रकार बदलते हैं:

  • उत्पाद उपश्रेणीनिकालें और लार्जफ़ोटो परिणाम सेट से कॉलम।
  • क्वेरी में पेजिंग को समायोजित करने के लिए OFFSET और FETCH का उपयोग करें। एक बार में केवल 10 उत्पादों के बारे में पूछें।
  • ProductSubcategoryIDजोड़ें ग्राहक के चयन के आधार पर WHERE क्लॉज में।
  • उत्पाद उपश्रेणी निकालें ORDER BY क्लॉज में कॉलम।

क्वेरी अब इस तरह होगी:

DECLARE @pageNumber TINYINT
DECLARE @noOfRows TINYINT =  10 -- each page will display 10 products at a time

SELECT
 a.ProductID
,a.Name AS ProductName
,a.ListPrice
,a.Color
,d.ThumbNailPhoto
FROM Production.Product a
INNER JOIN Production.ProductSubcategory b ON a.ProductSubcategoryID = b.ProductSubcategoryID
INNER JOIN Production.ProductProductPhoto c ON a.ProductID = c.ProductID
INNER JOIN Production.ProductPhoto d ON c.ProductPhotoID = d.ProductPhotoID
WHERE b.ProductCategoryID = 1 -- Bikes
AND a.ProductSubcategoryID = 2 -- Road Bikes
ORDER BY ProductName, a.Color
OFFSET (@pageNumber-1)*@noOfRows ROWS FETCH NEXT @noOfRows ROWS ONLY     
-- change the OFFSET and FETCH values based on what page the user is.

किए गए परिवर्तनों के साथ, क्या लॉब लॉजिकल रीड में सुधार होगा? सांख्यिकी आईओ अब रिपोर्ट करता है:

उत्पादफ़ोटो तालिका में अब 0 लॉब लॉजिकल रीड्स हैं - 665 लॉब लॉजिकल रीड्स डाउन से कोई नहीं। यह कुछ सुधार है।

टेकअवे

लॉब लॉजिकल रीड्स को कम करने के तरीकों में से एक इसे सरल बनाने के लिए क्वेरी को फिर से लिखना है।

अनावश्यक कॉलम हटाएं और लौटाई गई पंक्तियों को कम से कम आवश्यक तक कम करें। जब आवश्यक हो, पेजिंग के लिए OFFSET और FETCH का उपयोग करें।

यह सुनिश्चित करने के लिए कि क्वेरी परिवर्तनों ने लॉब लॉजिकल रीड्स और SQL क्वेरी प्रदर्शन में सुधार किया है, हमेशा STATISTICS IO की जाँच करें।

3. हाई वर्कटेबल/वर्कफाइल लॉजिकल रीड्स

अंत में, यह वर्कटेबल . का तार्किक अर्थ है और कार्यफ़ाइल . लेकिन ये टेबल क्या हैं? जब आप अपनी क्वेरी में उनका उपयोग नहीं करते हैं तो वे क्यों दिखाई देते हैं?

कार्यस्थल Having होना और कार्यफ़ाइल सांख्यिकी IO में प्रदर्शित होने का अर्थ है कि वांछित परिणाम प्राप्त करने के लिए SQL सर्वर को बहुत अधिक कार्य करने की आवश्यकता है। यह tempdb . में अस्थायी तालिकाओं का उपयोग करने का सहारा लेता है , अर्थात् वर्कटेबल्स और कार्यफ़ाइलें . जरूरी नहीं कि उनका सांख्यिकी IO आउटपुट में होना हानिकारक है, जब तक कि तार्किक रीड्स शून्य हैं, और इससे सर्वर को कोई परेशानी नहीं हो रही है।

ये तालिकाएं तब दिखाई दे सकती हैं, जब अन्य के बीच कोई ORDER BY, GROUP BY, CROSS JOIN, या DISTINCT हो।

वर्कटेबल/वर्कफ़ाइल लॉजिकल रीड्स का उदाहरण

मान लें कि आपको कुछ उत्पादों की बिक्री के बिना सभी स्टोर से पूछताछ करने की आवश्यकता है।

आप शुरू में निम्नलिखित के साथ आते हैं:

SELECT DISTINCT
 a.SalesPersonID
,b.ProductID
,ISNULL(c.OrderTotal,0) AS OrderTotal
FROM Sales.Store a
CROSS JOIN Production.Product b
LEFT JOIN (SELECT
            b.SalesPersonID
           ,a.ProductID
           ,SUM(a.LineTotal) AS OrderTotal
           FROM Sales.SalesOrderDetail a
           INNER JOIN Sales.SalesOrderHeader b ON a.SalesOrderID = b.SalesOrderID
           WHERE b.SalesPersonID IS NOT NULL
           GROUP BY b.SalesPersonID, a.ProductID, b.OrderDate) c ON a.SalesPersonID  
                                                                  = c.SalesPersonID
                                                  AND b.ProductID = c.ProductID
WHERE c.OrderTotal IS NULL
ORDER BY a.SalesPersonID, b.ProductID

इस क्वेरी ने 3649 पंक्तियाँ लौटा दीं:

आइए देखें कि सांख्यिकी आईओ क्या कहता है:

यह ध्यान देने योग्य है कि कार्यस्थल तार्किक पठन 7128 हैं। कुल तार्किक पठन 8853 हैं। यदि आप निष्पादन योजना की जांच करते हैं, तो आपको बहुत सारी समानताएं, हैश मिलान, स्पूल और अनुक्रमणिका स्कैन दिखाई देंगे।

वर्कटेबल/वर्कफ़ाइल लॉजिकल रीड्स को कम करना

मैं संतोषजनक परिणाम के साथ एक भी चयन कथन नहीं बना सका। इस प्रकार सेलेक्ट स्टेटमेंट को कई प्रश्नों में विभाजित करने का एकमात्र विकल्प है। नीचे देखें:

SELECT DISTINCT
 a.SalesPersonID
,b.ProductID
INTO #tmpStoreProducts
FROM Sales.Store a
CROSS JOIN Production.Product b

SELECT
 b.SalesPersonID
,a.ProductID
,SUM(a.LineTotal) AS OrderTotal
INTO #tmpProductOrdersPerSalesPerson
FROM Sales.SalesOrderDetail a
INNER JOIN Sales.SalesOrderHeader b ON a.SalesOrderID = b.SalesOrderID
WHERE b.SalesPersonID IS NOT NULL
GROUP BY b.SalesPersonID, a.ProductID

SELECT
 a.SalesPersonID
,a.ProductID
FROM #tmpStoreProducts a
LEFT JOIN #tmpProductOrdersPerSalesPerson b ON a.SalesPersonID = b.SalesPersonID AND 
                                               a.ProductID = b.ProductID
WHERE b.OrderTotal IS NULL
ORDER BY a.SalesPersonID, a.ProductID

DROP TABLE #tmpProductOrdersPerSalesPerson
DROP TABLE #tmpStoreProducts

यह कई पंक्तियाँ लंबी है, और यह अस्थायी तालिकाओं का उपयोग करती है। अब, देखते हैं कि सांख्यिकी IO क्या प्रकट करता है:

इस सांख्यिकीय रिपोर्ट की लंबाई पर ध्यान केंद्रित न करने का प्रयास करें - यह केवल निराशाजनक है। इसके बजाय, प्रत्येक तालिका से तार्किक पठन जोड़ें।

कुल 1279 के लिए, यह एक महत्वपूर्ण कमी है, क्योंकि यह एकल SELECT कथन से 8853 तार्किक पठन था।

हमने अस्थायी तालिकाओं में कोई अनुक्रमणिका नहीं जोड़ी है। SalesOrderHeader . में बहुत अधिक रिकॉर्ड जोड़े जाने पर आपको इसकी आवश्यकता हो सकती है और SalesOrderDetail . लेकिन आप समझ गए हैं।

टेकअवे

कभी-कभी 1 सेलेक्ट स्टेटमेंट अच्छा लगता है। हालांकि, परदे के पीछे सच इसके विपरीत है। कार्यस्थल और कार्यफ़ाइलें उच्च तार्किक पठन के साथ आपके SQL क्वेरी प्रदर्शन में पिछड़ जाते हैं।

यदि आप क्वेरी को फिर से बनाने के लिए किसी अन्य तरीके के बारे में नहीं सोच सकते हैं, और अनुक्रमणिका बेकार हैं, तो "विभाजित और जीतें" दृष्टिकोण का प्रयास करें। कार्यस्थल और कार्यफ़ाइलें SSMS के संदेश टैब में अभी भी प्रकट हो सकता है, लेकिन तार्किक पठन शून्य होगा। इसलिए, समग्र परिणाम कम तार्किक पठन होगा।

SQL क्वेरी प्रदर्शन और सांख्यिकी IO में बॉटमलाइन

इन 3 खराब I/O आँकड़ों में क्या बड़ी बात है?

SQL क्वेरी के प्रदर्शन में अंतर रात और दिन जैसा होगा यदि आप इन नंबरों पर ध्यान दें और उन्हें कम करें। हमने तार्किक पठन को कम करने के लिए केवल कुछ तरीके प्रस्तुत किए हैं जैसे:

  • उपयुक्त अनुक्रमणिका बनाना;
  • प्रश्नों को सरल बनाना - अनावश्यक कॉलम हटाना और परिणाम सेट को कम करना;
  • एक प्रश्न को अनेक प्रश्नों में विभाजित करना।

आंकड़े अपडेट करना, इंडेक्स को डीफ़्रैग्मेन्ट करना और सही FILLFACTOR सेट करना और भी बहुत कुछ है। क्या आप टिप्पणी अनुभाग में इसमें और जोड़ सकते हैं?

अगर आपको यह पोस्ट पसंद आए तो कृपया इसे अपने पसंदीदा सोशल मीडिया पर शेयर करें।


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Hadoop इनपुट आउटपुट सिस्टम को समझना

  2. पंक्ति लक्ष्य, भाग 4:विरोधी विरोधी पैटर्न में शामिल हों

  3. JavaFX चार्ट API के साथ कार्य करना

  4. संबंधपरक डेटाबेस

  5. क्लाउड साइट्स में डेटाबेस बनाना