मैं एज़्योर SQL डेटाबेस से एक खराब निष्पादन योजना कैसे निकाल सकता हूं?


12

DBCC FREEPROCCACHEAzure SQL DB में काम नहीं करता है। मैं किसी और तरह से कैश से बाहर निकलने की योजना को कैसे मजबूर कर सकता हूं जिससे उत्पादन प्रणाली को नुकसान न पहुंचे (यानी मैं सिर्फ टेबल विली नीली नहीं जा सकता)? यह विशेष रूप से एंटिटी फ्रेमवर्क द्वारा निर्मित SQL के लिए है, इसलिए ये स्व-प्रबंधित संग्रहित प्रोक्स नहीं हैं - यह प्रभावी रूप से गतिशील SQL है।

(स्रोत खराब इंडेक्स था -> खराब आँकड़े, आदि। यह सब तय हो गया है, लेकिन एक बुरा प्लान नहीं चलेगा।)

अद्यतन: मैंने @ मर्डीनी के समाधान का चयन किया क्योंकि वह पहले वहां गया था। हालाँकि, मैं सफलतापूर्वक काम करने के लिए @Aaron बर्ट्रेंड की स्क्रिप्ट का उपयोग कर रहा हूं। मदद के लिए सभी को धन्यवाद !!


क्या आप Azure में एक sp_recompile कर सकते हैं?
mrdenny

हाँ। मैं इसे किस पर चलाऊंगा? हमारे पास कोई संग्रहीत प्रोक्स नहीं है। यह डायनेमिक SQL रन है sp_executesql
१०:१६ पर जैसिडियन

2
आप इसे मेज पर स्वयं चला सकते हैं और उस योजना का उपयोग करना चाहिए जो उस तालिका का उपयोग करती है। (यदि यह काम करता है तो मैं इसका उत्तर दूंगा।)
मृदुलि

1
मैंने सिर्फ एक मेज पर यह कोशिश की और प्रसंस्करण के दौरान यह स्पष्ट रूप से तालिका को ताले में बंद कर देता है। मैंने इसे केवल 24 रिकॉर्ड के साथ 10-कॉलम की मेज पर आज़माया और इसे खत्म होने में एक मिनट का समय लगा। इस समय के दौरान, मैं तालिका को क्वेरी करने में असमर्थ था। मैं उत्पादन में हमारे असली तालिकाओं पर ऐसा कुछ नहीं चला सकता!
जैक्सिडियन

1
लानत है, कि एक bummer है। ऐसा लगता है कि आपको एक अशक्त स्तंभ जोड़ने की तरह एक स्कीमा परिवर्तन करने की आवश्यकता होगी, फिर इसे छोड़ दें। कि कैश को भी मिटा देंगे और जल्दी होना चाहिए। परीक्षण सुनिश्चित करने के लिए बताएगा।
mrdenny

जवाबों:


12

Azure SQL अब सीधे इसका समर्थन करता है

Azure SQL डेटाबेस बिना किसी हैक के वर्तमान उपयोगकर्ता डेटाबेस के खरीद कैश को साफ़ करने का समर्थन करता है:

ALTER DATABASE SCOPED CONFIGURATION CLEAR PROCEDURE_CACHE;

अतिरिक्त जानकारी

निम्नलिखित स्क्रिप्ट ( शान्नोन गोवेन द्वारा ) का उपयोग प्रक्रिया को चरण-दर-चरण देखने के लिए किया जा सकता है:

-- run this script against a user database, not master
-- count number of plans currently in cache
select count(*) from sys.dm_exec_cached_plans;

-- Executing this statement will clear the procedure cache in the current database, which means that all queries will have to recompile.
ALTER DATABASE SCOPED CONFIGURATION CLEAR PROCEDURE_CACHE;

-- count number of plans in cache now, after they were cleared from cache
select count(*) from sys.dm_exec_cached_plans;

-- list available plans
select * from sys.dm_exec_cached_plans;

मैंने अभी तक यह कोशिश नहीं की है, लेकिन अगर यह वास्तव में कार्यात्मक है, तो यह 2017 की शुरुआत के रूप में "सबसे अच्छा" उत्तर है। इसके लिए धन्यवाद - मुझे इसमें कोई सुराग नहीं था! :-)
जैक्सिडियन

मैंने यह कोशिश की है (एक प्रीमियम डीबी पर) और यह काम किया।
रेमी लेमरचंद

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

बस फिर से देखने के लिए, मैंने इसका इस्तेमाल किया है और इसने मेरे लिए अच्छा काम किया है! मैं टोड के उत्तर में कुछ अतिरिक्त लिपियों को जोड़ रहा हूं ताकि इसे समृद्ध किया जा सके लेकिन उनकी पोस्ट ने सिर पर कील ठोक दी।
१२:१४ पर जैसिडियन

यह मेरे लिए काम करने के लिए प्रतीत नहीं होता है - यह सिर्फ निष्पादित करता है लेकिन सूचियां अभी भी भरी हुई हैं - मैं एसक्यूएल एज़्योर पर हूँ - क्या गलत हो सकता है?
डिर्क बोअर

12

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

इसके लिए क्रेडिट की तलाश नहीं है, लेकिन कई तालिकाओं के खिलाफ एक ही ऑपरेशन करने के लिए गतिशील एसक्यूएल का निर्माण करना बहुत आसान है:

DECLARE @sql NVARCHAR(MAX) = N'';

SELECT @sql += N'ALTER TABLE '
  + QUOTENAME(SCHEMA_NAME([schema_id])) 
  + '.' + QUOTENAME(name) + ' ADD fake_column INT NULL;
  ALTER TABLE ' 
  + QUOTENAME(SCHEMA_NAME([schema_id]))
  + '.' + QUOTENAME(name) + ' DROP COLUMN fake_column;'
FROM sys.tables
--WHERE name IN, LIKE, etc.

PRINT @sql;

-- if the command > 8K, you can see the second chunk e.g.

PRINT SUBSTRING(@sql, 8001, 8000);

--EXEC sys.sp_executesql @sql;

(मैंने इस "गतिशील एसक्यूएल की लंबाई" के मुद्दे पर एक टिप लिखा ...)


मेरे मामले में, उन सभी को हटा देना बुरे लोगों को वहां छोड़ने के लिए बहुत बेहतर है। सर उठाने के लिए धन्यवाद। मैं जानता हूँ कि आपको बता नहीं सकता मुझे सुविधाओं, लेकिन आप मुझे बता सकते हैं जब आप नहीं रह गया है चीज़ों के बारे में बात नहीं कर सकते के बारे में बात के बारे में प्रतिबंधित किया जा सकता है? ;-)
जैक्सिडियन

यह भी वर्गीकृत है, क्षमा करें। :-)
हारून बर्ट्रेंड

यकीन नहीं होता कि लिंक से आपका क्या मतलब है। मेरे कहने का मतलब है कि nvarchar(max)अगर मैं इसे बदलूं तो आपका चर ४००० वर्णों, char००० वर्णों के बाद एक सीमा से टकराता है varchar(max)। उस सटीक स्क्रिप्ट को चलाना। हमारे पास ~ 450 टेबल हैं, इसलिए हमने आसानी से मारा (~ 30/60 टेबल)। varchar(max)मान्य सिंटैक्स है, यह इसके समान है varchar(8000), और nvarchar(max)इसके समान है nvarchar(4000)
जैक्सिडियन

3
ठीक है हाँ, जब आप PRINTकमांड देते हैं, तो यह केवल 8000 बाइट दिखाता है। यह PRINTआदेश की एक सीमा है , न कि एज़्योर। यदि आप कमांड चलाते हैं, तो यह तब भी काम करेगा जब आप पूरी तरह से निरीक्षण नहीं कर सकते।
हारून बर्ट्रेंड

... दो, माफ करना, मुझे लगता है कि तुम सही हो! मुझे सही करने के लिए धन्यवाद! ऐसा तब होता है जब आपकी पत्नी आपसे 25 मिनट पहले छोड़ने की उम्मीद कर रही थी ... ;-) यह स्क्रिप्ट मेरे लिए पूरी तरह से काम करती है!
जैसिडियन

6

तालिका में एक अशक्त स्तंभ जोड़ें, फिर स्तंभ ड्रॉप करें। यह SQL को उस ऑब्जेक्ट के लिए कैश फ्लश करने के लिए मजबूर करेगा।

सभी तालिकाओं को करने के लिए, एक कर्सर को चाल करना चाहिए। बस एक कॉलम नाम का उपयोग करें जो 'zzzzzz_go_away' या किसी भी तालिका में मौजूद नहीं होगा।


4

Azure SQL डेटाबेस वर्तमान में समर्थन नहीं करता है DBCC FREEPROCCACHE, इसलिए आप मैन्युअल रूप से कैश से निष्पादन योजना नहीं निकाल सकते हैं। हालाँकि, यदि आप क्वेरी ( ALTER TABLE/ ALTER VIEW) द्वारा संदर्भित तालिका या दृश्य में परिवर्तन करते हैं, तो योजना को कैश से हटा दिया जाएगा। ( संदर्भ ।)


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

1
आप संभवतः एक डमी कॉलम जोड़ सकते हैं और फिर इसे छोड़ सकते हैं। यह कैश से योजना को हटा देगा। टेबल कितनी बड़ी है?
परिजन शाह

यह समाधान समाप्त हो रहा है, जैसा कि @mrdenny द्वारा अनुशंसित है। सहायता के लिए धन्यवाद!! :-)
जैक्सिडियन

1
धन्यवाद ... बस कुछ ही समय में कम सेकंड .. स्टैकटेक्चेंज पर कुछ अन्य पोस्ट का जवाब दे रहा था ...
परिजन शाह

1

सभी निष्पादन योजना को साफ़ करने के लिए, इसका उपयोग करें:

    SET NOCOUNT ON

DECLARE @lcl_name VARCHAR(100)
DECLARE @addcolumnSql nVARCHAR(MAX)
DECLARE @dropcolumnSql nVARCHAR(MAX)

DECLARE cur_name CURSOR FOR
SELECT name
FROM sysobjects
WHERE type = 'U'
OPEN cur_name
FETCH NEXT FROM cur_name INTO @lcl_name
WHILE @@Fetch_status = 0
BEGIN
set @addcolumnSql = 'alter table [' + @lcl_name + '] add temp_col_to_clear_exec_plan bit'
EXEcute sp_executesql @addcolumnSql
print @addcolumnSql
set @dropcolumnSql = 'alter table [' + @lcl_name + '] drop column temp_col_to_clear_exec_plan'
EXEcute sp_executesql @dropcolumnSql
print @dropcolumnSql
--  EXEC (@lcl_name )
FETCH NEXT FROM cur_name INTO @lcl_name
END
CLOSE cur_name
DEALLOCATE cur_name
SET NOCOUNT OFF

यदि आप किसी तालिका को बदलते हैं या इसे संदर्भित करते हुए देखते हैं, तो निष्पादन योजना साफ़ हो जाती है।

थोड़ा और यहाँ समझाया गया http://christianarg.wordpress.com/2013/08/22/remove-execution-plans-from-the-procedure-cache-in-sql-azure/

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