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

विस्तारित घटनाओं का उपयोग करके निष्पादन योजना चेतावनियों को कैप्चर करें

हम इस सप्ताह डबलिन में IEPTO2 पढ़ा रहे हैं (और यदि आयरलैंड इस जीवनकाल में देखने के लिए आपके स्थानों की सूची में नहीं है, तो आपको इसे अवश्य जोड़ना चाहिए ... यह यहाँ शानदार है) और आज मैंने क्वेरी प्लान विश्लेषण मॉड्यूल को समाप्त किया। एक चीज जो मैं कवर करता हूं वह दिलचस्प चीजें हैं जिन्हें आप क्वेरी प्लान में पा सकते हैं, उदाहरण के लिए:

  • NoJoinPredicate (2005 और उच्चतर)
  • ColumnsWithNoStatistics (2005 और उच्चतर)
  • बेमेल इंडेक्स (2008 और उच्चतर)
  • PlanAffectingConvert (2012 और उच्चतर)

जब आप ट्यूनिंग कर रहे हों, तो ये विशेषताएँ देखने में अच्छी होती हैं, जब आप किसी एकल योजना या योजनाओं के सेट को देख रहे होते हैं। लेकिन अगर आप थोड़ा और सक्रिय होना चाहते हैं, तो आप प्लान कैश को माइन करना शुरू कर सकते हैं और वहां उन्हें ढूंढ सकते हैं। बेशक, ऐसा करने के लिए कुछ XQuery लिखने की आवश्यकता है, क्योंकि योजनाएँ XML हैं (शोप्लान स्कीमा के बारे में विवरण के लिए, देखें:http://schemas.microsoft.com/sqlserver/2004/07/showplan/)। मुझे एक्सएमएल पसंद नहीं है, हालांकि कोशिश करने की कमी के लिए नहीं, और जब उपस्थित लोगों में से एक ने पूछा कि क्या आप उन प्रश्नों को कैप्चर कर सकते हैं जिनमें विस्तारित घटनाओं के माध्यम से NoJoinPredicate विशेषता थी, तो मैंने सोचा, "क्या एक अच्छा विचार है, मुझे जांचना होगा । "

निश्चित रूप से, उसके लिए एक ईवेंट है। मेरे द्वारा ऊपर सूचीबद्ध सभी चार लोगों के लिए एक ईवेंट है:

  • मिसिंग_जॉइन_प्रेडिकेट
  • अनुपलब्ध_स्तंभ_आंकड़े
  • बेमेल_फिल्टर_इंडेक्स
  • योजना_प्रभावित_रूपांतरित करें

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

-- Remove event session if it exists
IF EXISTS (SELECT 1 FROM [sys].[server_event_sessions]
WHERE [name] = 'InterestingPlanEvents')
BEGIN
  DROP EVENT SESSION [InterestingPlanEvents] ON SERVER
END
GO
 
-- Define event session
CREATE EVENT SESSION [InterestingPlanEvents]
ON SERVER
ADD EVENT sqlserver.missing_column_statistics
(
  ACTION(sqlserver.database_id,sqlserver.plan_handle,sqlserver.sql_text)
  WHERE ([package0].[equal_boolean]([sqlserver].[is_system],(0))
    AND [sqlserver].[database_id]>(4))
),
ADD EVENT sqlserver.missing_join_predicate
(
  ACTION(sqlserver.database_id,sqlserver.plan_handle,sqlserver.sql_text)
  WHERE ([sqlserver].[is_system]=(0) AND [sqlserver].[database_id]>(4))
),
ADD EVENT sqlserver.plan_affecting_convert
(
  ACTION(sqlserver.database_id,sqlserver.plan_handle,sqlserver.sql_text)
  WHERE ([package0].[equal_boolean]([sqlserver].[is_system],(0))
    AND [sqlserver].[database_id]>(4))
),
ADD EVENT sqlserver.unmatched_filtered_indexes
(
  ACTION(sqlserver.plan_handle,sqlserver.sql_text)
  WHERE ([package0].[equal_boolean]([sqlserver].[is_system],(0))
    AND [sqlserver].[database_id]>(4))
)
ADD TARGET package0.event_file
(
  SET filename=N'C:\temp\InterestingPlanEvents' /* change location if appropriate */
)
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,
MAX_DISPATCH_LATENCY=5 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,
TRACK_CAUSALITY=ON,STARTUP_STATE=OFF)
GO
 
-- Start the event session
ALTER EVENT SESSION [InterestingPlanEvents] ON SERVER STATE=START;
GO

एक बार जब हमारे पास ईवेंट सत्र चल रहा होता है, तो हम इन घटनाओं को नीचे दिए गए नमूना कोड के साथ उत्पन्न कर सकते हैं। ध्यान दें कि यह कोड एडवेंचरवर्क्स2014 की एक नई स्थापना मानता है। यदि आपके पास एक नहीं है, तो आपको [HumanResources] में [HireDate] कॉलम से पूछताछ करने पर शायद आपको अनुपलब्ध_column_statistics ईवेंट फ़ायर दिखाई न दे।[कर्मचारी]।

-- These queries assume a FRESH restore of AdventureWorks2014
ALTER DATABASE [AdventureWorks2014] SET AUTO_CREATE_STATISTICS OFF;
GO
 
USE [AdventureWorks2014];
GO
 
CREATE INDEX [NCI_SalesOrderHeader] ON [Sales].[SalesOrderHeader] (
[PurchaseOrderNumber], [CustomerID], [TotalDue], [DueDate]
)
WHERE [SubTotal] > 10000.00;
GO
 
/*
No join predicate
NOTE: We clear procedure here because the event ONLY fires for the *initial* compilation
*/
DBCC FREEPROCCACHE; /* Not for production use */
 
SELECT [h].[SalesOrderID], [d].[SalesOrderDetailID], [h].[CustomerID]
FROM [Sales].[SalesOrderDetail] [d],
[Sales].[SalesOrderHeader] [h]
WHERE [d].[ProductID] = 897;
GO
 
-- Columns with no statistics
SELECT [BusinessEntityID], [NationalIDNumber], [JobTitle], [HireDate], [ModifiedDate]
FROM [HumanResources].[Employee]
WHERE [HireDate] >= '2013-01-01';
GO
 
-- Unmatched Index
DECLARE @Total MONEY = 10000.00;
 
SELECT [PurchaseOrderNumber], [CustomerID], [TotalDue], [DueDate]
FROM [Sales].[SalesOrderHeader]
WHERE [SubTotal] > @Total;
GO
 
-- Plan Affecting Convert
SELECT [BusinessEntityID], [NationalIDNumber], [JobTitle], [HireDate], [ModifiedDate]
FROM [HumanResources].[Employee]
WHERE [NationalIDNumber] = 345106466;
GO
 
ALTER EVENT SESSION [InterestingPlanEvents]
ON SERVER
STATE=STOP;
GO
 
DROP EVENT SESSION [InterestingPlanEvents]
ON SERVER;
GO

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

ALTER DATABASE [AdventureWorks2014] SET AUTO_CREATE_STATISTICS ON;
GO
 
DROP INDEX [NCI_SalesOrderHeader] ON [Sales].[SalesOrderHeader];
GO

चूंकि मैंने ईवेंट सत्र रोक दिया है, इसलिए हमने जो कैप्चर किया है उसे देखने के लिए मैं SSMS में आउटपुट फ़ाइल खोलूंगा:

विस्तारित ईवेंट से आउटपुट

लापता जॉइन विधेय के साथ हमारी पहली क्वेरी के लिए, हमारे पास एक घटना है जो दिखाई देती है, और मैं sql_text फ़ील्ड में क्वेरी के लिए टेक्स्ट देख सकता हूं। हालांकि, मैं वास्तव में योजना को देखना चाहता हूं, इसलिए मैं plan_handle ले सकता हूं और sys.dm_exec_query_plan:

देख सकता हूं।
SELECT query_plan FROM sys.dm_exec_query_plan
(0x06000700E2200333405DD12C0000000001000000000000000000000000000000000000000000000000000000);

और उसे SQL संतरी योजना एक्सप्लोरर में खोलना:

प्रीडिकेट में शामिल न होना

योजना में नेस्टेड लूप (लाल एक्स) में लापता शामिल होने का एक दृश्य संकेतक है, और यदि मैं उस पर होवर करता हूं तो मुझे चेतावनी दिखाई देती है (और यह योजना के लिए एक्सएमएल में है)। बढ़िया… अब मैं इस क्वेरी को फिर से लिखने के बारे में अपने डेवलपर से बात कर सकता हूं।

अगला ईवेंट अनुपलब्ध स्तंभ आँकड़ों के लिए है। मैंने एडवेंचरवर्क्स2014 डेटाबेस के लिए AUTO_CREATE_STATISTICS को बंद करके इस स्थिति को पूरी तरह से मजबूर कर दिया। मैं किसी भी तरह, आकार या रूप में इसकी अनुशंसा नहीं करता हूं। यह विकल्प डिफ़ॉल्ट रूप से सक्षम है और मैं इसे हमेशा सक्षम रहने की सलाह देता हूं। हालाँकि, इसे बंद करना इस घटना को उत्पन्न करने का सबसे आसान तरीका है। मेरे पास फिर से sql_text फ़ील्ड में क्वेरी है, लेकिन मैं प्लान को खींचने के लिए फिर से plan_handle का उपयोग करूंगा:

SELECT query_plan FROM sys.dm_exec_query_plan
(0x060007004448323810921C360000000001000000000000000000000000000000000000000000000000000000);

सांख्यिकी अनुपलब्ध

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

अब, शेष कार्यक्रम कुछ अधिक दिलचस्प हैं।

आप देखेंगे कि हमारे पास तीन बेजोड़_फिल्टर_इंडेक्स इवेंट हैं। मुझे अभी तक यह निर्धारित नहीं करना है कि क्यों, लेकिन मैं इस पर काम कर रहा हूं और अगर मैं इसे हल करता/करती हूं तो टिप्पणियों में पोस्ट करूंगा। अभी के लिए, यह पर्याप्त है कि मेरे पास घटना है, और घटना के भीतर हम वस्तु की जानकारी भी देख सकते हैं, इसलिए मुझे प्रश्न में सूचकांक पता है:

NCI_SalesOrderHeader अनुक्रमणिका अनुपलब्ध अनुक्रमणिका ईवेंट द्वारा संदर्भित

और मैं क्वेरी योजना खोजने के लिए फिर से plan_handle ले सकता हूं:

बेजोड़ अनुक्रमणिका

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

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

SELECT query_plan FROM sys.dm_exec_query_plan
(0x0600070023747010E09E1C360000000001000000000000000000000000000000000000000000000000000000);

परिवर्तित करने की योजना बनाएं

योजना से रूपांतरण विवरण

हम फिर से अपने मित्र, पीले त्रिकोण को SELECT ऑपरेटर में देखते हैं, और XML के भीतर हम PlanAffectingConvert विशेषता पा सकते हैं। यह विशेषता SQL Server 2012 शोप्लान स्कीमा में जोड़ी गई थी, इसलिए यदि आप पहले वाला संस्करण चला रहे हैं, तो आपको योजना में यह दिखाई नहीं देगा। इस चेतावनी को हल करने के लिए थोड़ा और काम करने की आवश्यकता हो सकती है - आपको यह समझने की आवश्यकता है कि आपके पास डेटा प्रकार बेमेल कहां है और क्यों, और फिर या तो कोड या स्कीमा को संशोधित करना शुरू करें ... दोनों को प्रतिरोध के साथ पूरा किया जा सकता है। जोनाथन के पास एक पोस्ट है जो अंतर्निहित रूपांतरण पर अधिक विस्तार से चर्चा करती है, जो कि शुरू करने के लिए एक अच्छी जगह है यदि आपने पहले रूपांतरण मुद्दों के साथ काम नहीं किया है।

सारांश

ईवेंट की विस्तारित ईवेंट लाइब्रेरी लगातार बढ़ती जा रही है, और SQL सर्वर में समस्या निवारण करते समय विचार करने वाली एक बात यह है कि क्या आप वह जानकारी प्राप्त कर सकते हैं जिसे आप किसी अन्य तरीके से प्राप्त कर रहे हैं। शायद इसलिए कि यह आसान है (मुझे यकीन है कि एक्सएमएल से एक्सई पसंद है!), या क्योंकि यह अधिक कुशल है, या आपको अधिक विवरण देता है। चाहे आप सक्रिय रूप से अपने परिवेश में क्वेरी मुद्दों की तलाश कर रहे हों, या किसी समस्या पर प्रतिक्रिया कर रहे हों, जिसे किसी ने रिपोर्ट किया है, लेकिन आपको इसे खोजने में समस्या हो रही है, विस्तारित ईवेंट विचार करने के लिए एक व्यवहार्य विकल्प है, विशेष रूप से SQL सर्वर में अधिक नई सुविधाएँ जोड़ी जाती हैं।

  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. उन्नत एसक्यूएल:क्रॉस लागू करें और बाहरी आवेदन करें

  2. एसएसएएस के लिए विस्तारित कार्यक्रम

  3. डेटाबेस स्तर के संयोजन को समझना और डेटाबेस के लिए इसे बदलने का प्रभाव

  4. एसक्यूएल शुरुआती के लिए (!=) ऑपरेटर के बराबर नहीं है

  5. NoSQL क्या है और इसका उपयोग कैसे किया जाता है?