6

मेरे पास SQL ​​Server 2012 में एक बहु-किरायेदार डेटाबेस है जहां प्रत्येक किरायेदार की पंक्तियों को tenant_id कॉलम (उर्फ Shared Database, Shared Schema दृष्टिकोण) द्वारा पहचाना जाता है। कुछ किरायेदारों, विशेष रूप से नए लोगों में बहुत कम पंक्तियां होती हैं, जबकि अन्य में बहुत से लोग होते हैं।बहु-किरायेदार SQL सर्वर डेटाबेस और पैरामीटर स्नीफिंग

एसक्यूएल सर्वर की क्वेरी अनुकूलक सामान्य रूप से, एक प्रश्न अपनी पहली निष्पादन के दौरान प्रदान की मानकों के आधार पर योजना बनाता है तो भविष्य सभी प्रश्नों के लिए इस योजना भले ही विभिन्न मापदंडों प्रदान की जाती हैं फिर से उपयोग करता है। इसे parameter sniffing के रूप में जाना जाता है।

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

एक क्वेरी संकेत है जिसका उपयोग आप SQL सर्वर को कैशिंग क्वेरी योजनाओं (OPTIMIZE FOR UNKNOWN) से रोकने के लिए कर सकते हैं, लेकिन इसके परिणामस्वरूप कुछ अतिरिक्त ओवरहेड होते हैं क्योंकि पूछताछ हर बार क्वेरी योजना को पुन: उत्पन्न किया जा रहा है। एक अतिरिक्त समस्या यह है कि हम एंटीटी फ्रेमवर्क का उपयोग कर रहे हैं जो प्रश्नों पर OPTIMIZE FOR UNKNOWN संकेत निर्दिष्ट करने की कोई क्षमता प्रदान नहीं करता है।

तो सवाल है - क्या सूँघने पैरामीटर के लिए संबंध के साथ मल्टी-टेनेंट डेटाबेस के लिए सबसे अच्छा अभ्यास है? क्या प्रत्येक क्वेरी पर इसे निर्दिष्ट किए बिना पैरामीटर स्नीफिंग डेटाबेस-चौड़ा अक्षम करने का कोई तरीका है? यदि हां, तो क्या यह भी सबसे अच्छा तरीका है? क्या मुझे डेटा को किसी अन्य तरीके से विभाजित करना चाहिए? क्या कोई और दृष्टिकोण है जिसके बारे में मैं सोच नहीं रहा हूं?

+0

AFAIK, आप संग्रहीत प्रक्रिया का उपयोग कर इसे ठीक करने की जरूरत है। जब तक ईएफ की कुछ विशेषता न हो जो आपको इसके आसपास ले जाये। – RBarryYoung

+0

'अज्ञात के लिए ऑप्टिमाइज़' में आपके द्वारा वर्णित व्यवहार नहीं है। आप इसे 'विकल्प (रिकॉम्प्ली)' के साथ भ्रमित कर रहे हैं। यदि आप एंटरप्राइज़ संस्करण पर हैं तो आप संकेत प्रदान करने के लिए योजना मार्गदर्शिका देख सकते हैं। या कोई ट्रेस ध्वज (4136-) [अक्षम पैरामीटर पूरी तरह सूँघने] (http://support.microsoft.com/kb/980653) करने के लिए है, लेकिन उस ** उदाहरण ** डेटाबेस पर लागू होता है। –

उत्तर

3

मैं इसी तरह की समस्याओं पड़ा है, और इस तरह से मेरी पैरामीटर प्रदान करने के द्वारा सफलतापूर्वक इसे हल किया है:

CREATE PROCEDURE [dbo].[InsertAPCheck] 
@APBatchID int = Null, 
@BankAccountID int = Null 
AS 
    /* copy parameters to temporary variables */ 
    SELECT @xAPBatchId = APBatchId, @xBankAccountID = @BankAccountID 
. 
. 
/* now run the meat of your logic using the temp variables */ 
SELECT * FROM myTable where [email protected] 
दूसरे शब्दों में

, प्रत्येक पैरामीटर में पारित करने के लिए 1-1 से आधार पर एक स्थानीय चर बनाने और फिर केवल एसपी के तर्क के भीतर उन नए चरों का संदर्भ देना। मैं संभवतः कुछ अनुकूलन पर अनुपलब्ध हूं कि SQL सर्वर मेरे लिए कर सकता है, लेकिन सबसे महत्वपूर्ण बात यह है कि मुझे वास्तव में डरावनी प्रदर्शन पर याद आती है जब मैं परम स्लिमिंग करता हूं।

आपके मामले में, शायद आप ऐसा करने का प्रयास कर सकते हैं यह सिर्फ बहु-किरायेदार आईडी के लिए है (जो मुझे लगता है कि सभी एसपी के लिए पैरामीटर है?), और SQL सर्वर को शेष पैरामीटर को अनुकूलित करने दें यदि यह कर सकता है।

+0

यह अनिवार्य रूप से अनजान क्वेरी संकेत के लिए ऑप्टिमाइज़ करता है। दुर्भाग्य से मैं इकाई फ्रेमवर्क के साथ या तो दृष्टिकोण का उपयोग नहीं कर सकता क्योंकि मैं उत्पन्न होने वाली क्वेरी को संशोधित नहीं कर सकता। – Mike

संबंधित मुद्दे