SQL सर्वर लिंक्ड सर्वर का प्रदर्शन: दूरस्थ प्रश्न इतने महंगे क्यों हैं?


14

मेरे पास दो डेटाबेस सर्वर हैं, जो लिंक्ड सर्वर के माध्यम से जुड़े हैं। दोनों SQL सर्वर 2008R2 डेटाबेस हैं, और लिंक किए गए सर्वर कनेक्शन को वर्तमान लॉगिन के सुरक्षा संदर्भ का उपयोग करके एक नियमित "SQL सर्वर" लिंक के माध्यम से किया जाता है। लिंक किए गए सर्वर दोनों एक ही डेटासेंटर में हैं, इसलिए कनेक्शन एक मुद्दा नहीं होना चाहिए।

मैं निम्नलिखित क्वेरी का उपयोग यह जांचने के लिए करता हूं कि कॉलम के कौन से मूल्य identifierदूरस्थ रूप से उपलब्ध हैं, लेकिन स्थानीय रूप से नहीं।

SELECT 
    identifier 
FROM LinkedServer.RemoteDb.schema.[TableName]

EXCEPT

SELECT DISTINCT
    identifier 
FROM LocalDb.schema.[TableName] 

दोनों तालिकाओं पर स्तंभ पर गैर-क्लस्टर किए गए अनुक्रमित हैं identifier। स्थानीय रूप से लगभग 2.6M पंक्तियाँ हैं, केवल 54 दूर। फिर भी, जब क्वेरी योजना को देखते हैं, तो निष्पादन समय का 70% "दूरस्थ क्वेरी निष्पादित" करने के लिए समर्पित है। इसके अलावा, पूर्ण क्वेरी योजना का अध्ययन करते समय, अनुमानित स्थानीय पंक्तियों की संख्या 1इसके बजाय होती है 2695380(केवल बाद में आने वाली क्वेरी का चयन करते समय अनुमानित पंक्तियों की संख्या EXCEPT)। निष्पादन योजना इस क्वेरी को निष्पादित करते समय, वास्तव में एक लंबा समय लगता है।

यह मुझे आश्चर्यचकित करता है: यह क्यों है? क्या अनुमान "बस" रास्ता बंद है, या लिंक सर्वर पर दूरस्थ प्रश्न वास्तव में महंगे हैं?


2
BTW: यह "निष्पादन की अनुमानित संख्या" है जिसे आपको सूचकांक की तलाश में होना चाहिए। पंक्तियों की अनुमानित संख्या पंक्तियों का उत्पादन प्रति निष्पादन है जो तालिका में स्वयं पंक्तियों की संख्या से संबंधित नहीं होगा जब तक कि योजना में पूर्ण स्कैन न हो।
मार्टिन स्मिथ

जवाबों:


9

इस समय आपके पास जो योजना है वह मेरे लिए सबसे इष्टतम योजना है।

मैं अन्य उत्तरों में इस बात से सहमत नहीं हूँ कि यह दूरस्थ सर्वर को 2.6M पंक्तियाँ भेज रहा है।

यह योजना मुझे इस तरह दिखती है जैसे कि सुदूर क्वेरी से लौटी हुई 54 पंक्तियों में से प्रत्येक के लिए यह आपके स्थानीय तालिका में सूचकांक की तलाश कर रही है कि यह निर्धारित किया जाए कि यह मिलान है या नहीं। यह बहुत इष्टतम योजना है।

एक हैश ज्वाइन या मर्ज ज्वाइन के साथ प्रतिस्थापित करना काउंटरप्रोडक्टिव को टेबल का आकार दिया जाएगा और एक इंटरमीडिएट #tempटेबल को जोड़ने से एक अतिरिक्त कदम जुड़ जाएगा जो आपको कोई फायदा नहीं देता है।


6

एक दूरस्थ संसाधन से कनेक्ट करना महंगा है। अवधि।

किसी भी प्रोग्रामिंग वातावरण में सबसे महंगे ऑपरेशनों में से एक नेटवर्क IO है (हालांकि डिस्क IO इसे बौना करता है)।

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


आपको अपनी क्वेरी को इस तरह से संरचना करना चाहिए कि आप न्यूनतम डेटा को तार के पार स्थानांतरित करें। उम्मीद है कि DB आपके लिए अनुकूलन नहीं करेगा।

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

जो क्वेरी आप चला रहे हैं, वह EXCEPTक्लॉज़ को संसाधित करने के लिए रिमोट सर्वर को आसानी से 2.6M पंक्तियाँ भेज सकता है ।


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

@vstrien - यह हो सकता है। नेटवर्क कनेक्शन, विलंबता, संतृप्ति और अन्य कारकों पर निर्भर करता है। बिंदु होना - यह निर्धारक नहीं है।

@vstrien - मेरे उत्तर में अधिक जानकारी जोड़ी गई। मेरा मानना ​​है कि लिखित क्वेरी प्रसंस्करण के लिए स्थानीय पंक्तियों को दूरस्थ सर्वर पर भेज देगी।

2
आप इस तथ्य को कम करते हैं कि यह 2.6M पंक्तियों को दूरस्थ सर्वर से कहां भेज रहा है? मुझे दूरस्थ क्वेरी ऑपरेटरों के साथ योजनाओं का बहुत अनुभव नहीं है, लेकिन ऐसा लगता है कि जैसे कि 54 पंक्तियाँ दूरस्थ क्वेरी ऑपरेटर से निकल रही हैं तो यह स्थानीय तालिका के विरुद्ध विरोधी अर्ध सम्मिलित कर रही है।
मार्टिन स्मिथ

2
@Lieven - तार्किक हो सकता है लेकिन ऐसा नहीं लगता कि यह दिखाए गए प्लान से सही है।
मार्टिन स्मिथ

1

मैं एक विशेषज्ञ नहीं हूं, लेकिन अगर आप संघ, छोड़कर, या अंतर का उपयोग कर रहे हैं, तो आपको "डिस्टिंक्ट" का उपयोग करने की आवश्यकता नहीं है। LocalDb.schema। [TableName] से मूल्यों के आधार पर, क्वेरी प्रदर्शन में सुधार किया जा सकता है।

SELECT 
    identifier 
FROM LinkedServer.RemoteDb.schema.[TableName]

EXCEPT

SELECT 
    identifier 
FROM LocalDb.schema.[TableName]

0

Oded सही है, प्रदर्शन समस्या आपके दूरस्थ सर्वर को 2.6M पंक्तियाँ भेजने के कारण होती है।

इस समस्या को ठीक करने के लिए आप एक अस्थायी या स्मृति तालिका का उपयोग करके दूरस्थ डेटा (54 पंक्तियों) को आपको भेज सकते हैं।

एक अस्थायी तालिका का उपयोग करना

SELECT  identifier 
INTO    #TableName
FROM    LinkedServer.RemoteDb.schema.[TableName]

SELECT  identifier
FROM    #TableName
EXCEPT
SELECT  DISTINCT identifier 
FROM    LocalDb.schema.[TableName] 

DROP    #TableName

एक अस्थायी तालिका का उपयोग किसी भी घटना में कार्डिनैलिटी अनुमानों के साथ मदद कर सकता है, हालांकि एक नेस्टेड लूप केवल 54 पंक्तियों के लिए उचित लगता है।
मार्टिन स्मिथ

एक अस्थायी तालिका का उपयोग करना 54 पंक्तियों के साथ सही काम करता है; लेकिन दोनों तरफ बड़े तालिकाओं के मामले में यह अब संभव नहीं है। दो समान आकार वाली "विशाल" तालिकाओं के लिए आपका समाधान क्या होगा? किसी अन्य डेटाबेस में एक UserTable बनाना?
vstrien

1
@vstrien - दो समान आकार की विशाल तालिकाओं के लिए वास्तव में एक अच्छा समाधान नहीं है। शायद एक वितरित विभाजन दृश्य बनाना आपके लिए हितकारी है, लेकिन मुझे इससे कोई अनुभव नहीं है।
लेवेन कीर्सेमेकर्स

0

मुझे लगता है कि आप जिस रिमोट से क्वेरी कर रहे हैं, उस सर्वर को दूरस्थ तालिका की प्रतिकृति बनाना और फिर अपने सभी SQL को स्थानीय रूप से चलाना बेहतर है।

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