2014-06-17 8 views
10

मैं VIEWS से लिंक किए गए सर्वर के माध्यम से बड़ी मात्रा में डेटा निकालने जा रहा हूं। मैं SQL Server 2012 का उपयोग कर रहा है और जुड़ा हुआ सर्वर एसक्यूएल सर्वर 2008एसक्यूएल लिंक्ड सर्वर क्वेरी बहुत धीमी

मेरे चयन बयान

SELECT * INTO MY_LOCAL_TABLE 
FROM 
( SELECT * FROM LINKEDSERVER.DB.TABLE.VIEW 
    WHERE DATE>'2012-01-01' AND ID IN (SELECT ID FROM MY_LOCAL_VIEW) 
) Q 

मैं लगभग 700 + आईडी के लिए 300K पंक्तियों की उम्मीद कर रहा हूँ। इससे पहले कि इसमें कुछ घंटों लगते थे लेकिन अब यह 20 घंटे से अधिक समय लेता है !!

क्या आप इस दर्द के लिए कोई वैकल्पिक समाधान सुझा सकते हैं ??

अग्रिम में बहुत बहुत धन्यवाद!

+0

क्या विचार अनुक्रमित हैं? यदि नहीं, तो वे उप प्रश्न हैं? यदि नहीं, तो आप इन विचारों में एक इंडेक्स जोड़ सकते हैं। – Pricey

+0

और विचारों को अन्य विचारों को कॉल करते हैं, एक लिंक किए गए सर्वर पर एक प्रदर्शन संख्या-नहीं espcially। – HLGEM

+0

हां विचारों को ठीक से अनुक्रमित किया गया है। अगर मैं OPENQUERY का उपयोग करता हूं, तो क्या इससे कोई फर्क पड़ता है? या एसएसआईएस पैकेज? – arm

उत्तर

1

अन्य ने पहले से ही अनुक्रमण के बारे में सुझाव दिया है। तो मैं वहां नहीं जा रहा हूँ। एक और विकल्प का सुझाव है, अगर आपको लगता है कि आंतरिक क्वेरी

SELECT * FROM LINKEDSERVER.DB.TABLE.VIEW 
WHERE DATE>'2012-01-01' AND ID IN (SELECT ID FROM MY_LOCAL_VIEW) 

बदल सकता है inner join का उपयोग कर जब से तुम 700 + inlist तत्वों होने कहा एक joined क्वेरी करने के लिए। कोशिश करो।

SELECT lnv.* FROM LINKEDSERVER.DB.TABLE.VIEW lnv 
    inner join MY_LOCAL_VIEW mcv 
    on lnv.ID = mcv.ID 
    and lnv.DATE > '2012-01-01' 
+0

क्रॉस सर्वर अक्सर स्थानीय मशीन पर प्रतिलिपि बनाने वाली पूरी तालिकाओं का नेतृत्व करता है, यह केवल बहुत छोटी टेबल पर किया जाना चाहिए जो आप कर सकते हैं। – JiggsJedi

+0

@ जिग्सजेदी, यह काफी सच है (फिर से, मैंने अपने जवाब में उल्लेख किया है .. यह एक बार कोशिश करने के लिए एक सुझाव है) लेकिन अगर शामिल टेबल पर्याप्त नहीं हैं तो यह अधिकतर समय (मेरे अवलोकन के अनुसार) प्रदर्शन को बढ़ावा देगा। – Rahul

24

जब आप एक join में विशेष रूप से, इस तरह के [server].db.dbo.table के रूप में एक 4-भाग नाम का उपयोग, अक्सर कई बार पूरे तालिका स्थानीय मशीन है, जो स्पष्ट रूप से आदर्श नहीं है करने के लिए तार पर नकल की जाती है।

OPENQUERY का उपयोग करने के लिए एक बेहतर तरीका है - जिसे स्रोत (लिंक किए गए सर्वर) पर संभाला जाता है।

प्रयास करें:

SELECT * 
FROM OPENQUERY([LINKEDSERVER], 'SELECT * FROM DB.TABLE.VIEW WHERE DATE>'2012-01-01') 
AND ID IN (SELECT ID FROM MY_LOCAL_VIEW) 
इस दृष्टिकोण से जुड़ा हुआ सर्वर तारीख> एक्स के लिए सभी पंक्तियों वापस आ जाएगी, और उसके बाद स्थानीय सर्वर को फ़िल्टर करते हैं अपने स्थानीय तालिका में आईडी के द्वारा के साथ

बेशक, इंडेक्सिंग अभी भी SELECT * FROM DB.TABLE.VIEW WHERE DATE>'2012-01-01 करने के लिए एक कारक खेलेंगे।

-- copy local table to linked server by executing remote query 
    DECLARE @SQL NVARCHAR(MAX) 
    SET @SQL = 'SELECT ID INTO db.dbo.tmpTable FROM [SERVER].DB.DBO.MY_LOCAL_VIEW' 
    EXEC(@SQL) AT [LINKEDSERVER] 

    -- index remote table?!? 
    DECLARE @SQL NVARCHAR(MAX) 
    SET @SQL = 'CREATE INDEX [IXTMP] ON db.dbo.tmpTable (ID)' 
    EXEC(@SQL) AT [LINKEDSERVER] 

    -- run query on local machine against both remote tables 
    SELECT * 
    -- INTO sometable 
    FROM OPENQUERY([LINKEDSERVER], 'SELECT * 
            FROM DB.TABLE.VIEW 
            WHERE DATE>''2012-01-01'' 
            AND ID IN (SELECT ID FROM db.dbo.tmpTable)') 

    -- now drop remote temp table of id's 
    DECLARE @SQL NVARCHAR(MAX) 
    SET @SQL = 'DROP TABLE db.dbo.tmpTable' 
    EXEC(@SQL) AT [LINKEDSERVER] 

स्थानीय लोगों द्वारा देखे भी बड़ी है, तो:

एक और दृष्टिकोण है, जो मैं बड़े सबसेट पर उपयोग करते हैं, जैसे, दूरस्थ सर्वर से स्थानीय आईडी डंप तो दूर से यह सब संभाल करने, है आप रिमोट क्वेरी निष्पादित करने पर विचार कर सकते हैं जो स्थानीय मशीन पर ओपनक्वायरी का उपयोग करता है (मानते हैं कि रिमोट मशीन में एक लिंक के रूप में स्थानीय है)।

-- copy local table to linked server by executing remote query 
DECLARE @SQL NVARCHAR(MAX) 
SET @SQL = 'SELECT ID INTO db.dbo.tmpTable FROM OPENQUERY([SERVER], ''SELECT ID FROM DB.DBO.MY_LOCAL_VIEW'')' 
EXEC(@SQL) AT [LINKEDSERVER] 
+0

+1 वास्तव में एक अच्छा दृष्टिकोण है। इस बारे में नहीं पता था (मेरा मतलब है ओपनक्व्यू कारक)। – Rahul

+0

हम ... यह मेरे लिए अच्छा विचार प्रतीत होता है। मुझे यकीन नहीं है कि क्या मेरे पास लिंक किए गए सर्वर पर अस्थायी तालिका बनाने की सुविधा है या नहीं, लेकिन मैं निश्चित रूप से आपके सुझाव का प्रयास करूंगा क्योंकि लिंक किए गए सर्वर में 50K से अधिक आईडी हैं !! धन्यवाद – arm

+0

यह संभव है कि आईडी को एक वास्तविक अस्थायी तालिका (#table) में रखा जाए - सभी को उन्हें बनाने के लिए पहुंच होनी चाहिए, और इसे एक ही बार में चलाएं। आप हमेशा tempdb में उपयोगकर्ता तालिका बना सकते हैं, आपके काम डीबी में नहीं होना चाहिए। – JiggsJedi

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