मैं SQL सर्वर क्वेरी कैश से एक विशिष्ट खराब योजना कैसे निकालूं?


33

हमारे पास एक विशेष SQL Server 2008 क्वेरी है (संग्रहीत संग्रहीत नहीं है, लेकिन वही SQL स्ट्रिंग - हर 5 मिनट में निष्पादित होती है) जो रुक-रुक कर बहुत खराब क्वेरी योजना को कैश करती है।

यह क्वेरी सामान्य रूप से कुछ मिली सेकेंड में चलती है, लेकिन इस खराब क्वेरी प्लान के साथ, इसमें 30+ सेकंड लगते हैं।

उत्पादन डेटाबेस सर्वर पर संपूर्ण क्वेरी कैश को उड़ाए बिना, मैं SQL सर्वर 2008 से सिर्फ एक बुरी कैश्ड क्वेरी योजना को कैसे निकालूं ?


जवाबों:


39

मुझे कुछ बातें पता चलीं

select * from sys.dm_exec_query_stats

सभी कैश्ड क्वेरी प्लान दिखाएंगे। दुर्भाग्य से, कोई SQL पाठ वहाँ नहीं दिखाया गया है।

हालाँकि, आप इस तरह की योजनाओं के लिए SQL पाठ में शामिल हो सकते हैं:

select plan_handle, creation_time, last_execution_time, execution_count, qt.text
FROM 
   sys.dm_exec_query_stats qs
   CROSS APPLY sys.dm_exec_sql_text (qs.[sql_handle]) AS qt

यहाँ से WHEREएसक्यूएल को जानने के लिए एक खंड जोड़ने के लिए यह बहुत ही मामूली है कि मुझे पता है कि क्वेरी में है, और फिर मैं निष्पादित कर सकता हूं:

DBCC FREEPROCCACHE (plan_handle_id_goes_here)

क्वेरी प्लान कैश से प्रत्येक क्वेरी प्लान को निकालने के लिए। बिल्कुल आसान या सुविधाजनक नहीं है, लेकिन यह काम करने के लिए प्रतीत होता है ..

संपादित करें: संपूर्ण क्वेरी कैश को डंप करना भी काम करेगा, और यह जितना खतरनाक लगता है उससे कम खतरनाक है, कम से कम मेरे अनुभव में:

DBCC FREESYSTEMCACHE ('ALL') WITH MARK_IN_USE_FOR_REMOVAL;

2
एक योजना संकेत का उपयोग करने की सलाह कम नहीं है।
रेमस रुसानु

1
मुझे यह पता लगने के बाद कि मेरी क्वेरी जादुई रूप से ताज़ा है, यह बुरी योजना है, लेकिन अगली बार इसका परीक्षण करने की मेरी योजना है। एक योजना संकेत मदद नहीं करता है यदि क्वेरी 'वैकल्पिक-इटिस' से ग्रस्त है - जहां इसके कई वैकल्पिक पैरामीटर हैं और इसे एक सेट के लिए अनुकूलित किया गया है, तो एक अलग सेट के लिए चलाएं। ऐसी कोई इष्टतम योजना नहीं है जो इस तरह के प्रश्न के लिए संलग्न की जा सके। मापदंडों के एक सेट के लिए एक इष्टतम योजना है जो बदले में मापदंडों के एक और सेट के लिए भयानक है।
Nick.McD मत्स्यांगना

6

यदि आप जानते हैं कि अच्छी योजना कैसी दिखती है, तो बस एक योजना संकेत का उपयोग करें ।

आप एक विशिष्ट कैश प्रविष्टि को नहीं निकाल सकते, लेकिन आप पूरे कैश पूल को साफ कर सकते हैं DBCC FREESYSTEMCACHE(cachename/poolname)

यदि आपके पास योजना के हैंडल ( sysinos_exec_requests.plan_handle के लिए सेशन_आईडी के लिए मुसीबत के समय, निष्पादन के दौरान मुसीबत में, या sysinos_exec_query -stats पोस्ट निष्पादन से) का कैश नाम मिल सकता है :

select ce.name
from sys.dm_exec_cached_plans cp
join sys.dm_os_memory_cache_entries ce on cp.memory_object_address = ce.memory_object_address
where cp.plan_handle = @bad_plan

हालांकि सभी SQL योजनाओं का नाम 'SQL Plans' है जो DBCC FREESYSTEMCACHE के लिए सही विकल्प चुनता है ... कठिन विकल्प।

अद्यतन करें

कोई बात नहीं, भूल गया DBCC FREEPROCCACHE(plan_handle), हाँ जो काम करेगा।


1
DBCC FREEPROCCACHE के लिए एक plan_handle पास करने की क्षमता SQL सर्वर 2008 में उपलब्ध है और SQL Server 2005 में नहीं है।
मारियो

अगर sys.dm_exec_cached_plansइसमें से कोई प्रविष्टि नहीं है तो इसका क्या मतलब plan_handleहै sys.dm_exec_requests?
जोनाथन गिल्बर्ट

@JonathanGilbert इसका मतलब है कि योजना को कैश नहीं किया गया था, या इसे कैश से निकाल दिया गया था। देखें docs.microsoft.com/en-us/sql/relational-databases/...
Remus Rusanu

तो बस पुष्टि करने के लिए, भले ही मैं केवल उस क्वेरी को चलाना शुरू कर रहा हूं , और क्वेरी में कोई संकेत नहीं है कि इसे कैश न करें, इसे अनकैप किया जा सकता है क्योंकि SQL सर्वर ने इसे कैश नहीं करने का मूल्य निर्णय लिया है? यह नहीं होगा क्योंकि यह अभी भी चल रहा है, है ना? यदि यह योजना को कैश करने का निर्णय लेता है, तो यह उस बिंदु से सही कैश किया जाएगा जिस पर क्वेरी चलना शुरू होती है ?
जोनाथन गिल्बर्ट

1

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

DECLARE @SQL NVARCHAR(4000)
SELECT @SQL = 'SELECT * FROM Table WHERE Column LIKE @NAME OPTION (RECOMPILE)'
EXEC sp_executesql @SQL, N'@NAME varchar(15)', 'MyName' 
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.