2010-03-17 13 views
7

मैं मुसीबत का एक सा ओरेकल 10. मैं निम्नलिखित बयान उपयोग कर रहा हूँ में एक dblink भर में डालने में एक चयन के साथ हो रहा है भर में सम्मिलित करें:का चयन करें और dblink

INSERT INTO LOCAL.TABLE_1 (COL1, COL2) 
SELECT COL1, COL2 
FROM [email protected] s 
WHERE COL1 IN (SELECT COL1 FROM WORKING_TABLE) 

जब मैं बयान चलाने निम्नलिखित क्या है पर डीबी लिंक दूरस्थ सर्वर के खिलाफ चलाए हो जाता है:

SELECT /*+ OPAQUE_TRANSFORM */ "COL1", "COL2" 
FROM "REMOTE"."TABLE1" "S" 

अगर मैं चयन केवल चलाने के लिए और में डालने नहीं करते निम्नलिखित चलाया जाता है:

SELECT /*+ */ "A1"."COL1" 
    , "A1"."COL2" 
    FROM "REMOTE"."TABLE1" "A1" 
WHERE "A1"."COL1" = 
    ANY (SELECT "A2"."COL1" 
     FROM "LOCAL"."TABLE1"@! "A2") 

मुद्दा डालने के मामले में है, enitre तालिका को dblink में खींचा जा रहा है और फिर सीमित लोकली है जो टेबल आकार के बाद काफी समय लेता है। क्या सम्मिलित करने का कोई कारण इस तरह से व्यवहार को बदल देगा?

उत्तर

3

आप ड्राइविंग_साइट संकेत का उपयोग करना चाह सकते हैं। यहाँ एक अच्छा विवरण है: http://www.dba-oracle.com/t_sql_dblink_performance.htm

+0

मैंने पोस्ट करने से पहले प्रारंभिक क्वेरी में निम्नलिखित संकेत जोड़ने का प्रयास किया था, लेकिन एक ही परिणाम प्राप्त हुए। /* + DRIVING_SITE (/) 0/ वह dblink पक्ष पर ड्राइव करने के लिए सही संकेत देगा? – Domtar

2

के साथ खंड का इस्तेमाल के अपने पुनः प्राप्ति का अनुकूलन कर सकता है अपने काम को सेट करें:

WITH remote_rows AS 
    (SELECT /*+DRIVING_SITE(s)*/COL1, COL2 
     FROM [email protected] s 
     WHERE COL1 IN (SELECT COL1 FROM WORKING_TABLE)) 
INSERT INTO LOCAL.TABLE_1 (COL1, COL2) 
SELECT COL1, COL2 
FROM remote_rows 
+0

[यह उत्तर] (http://stackoverflow.com/questions/5885154/oracle-sql-insert-into-with-with-clause#5885845) दिखाता है कि यहां आपका वाक्यविन्यास सही नहीं है। – Alfabravo

3

यह DML की बात आती है, ओरेकल किसी भी driving_site संकेत की अनदेखी करने के लिए चुनता है और बयान निष्पादित करता है लक्ष्य साइट पर। तो मुझे संदेह है कि क्या आप इसे बदलने में सक्षम होंगे (ऊपर वर्णित दृष्टिकोण के साथ भी)। एक संभावित समाधान यह है कि आप दूरस्थ डेटाबेस पर LOCAL.TABLE1 के लिए समानार्थी बना सकते हैं और इसे अपने INSERT कथन में उपयोग कर सकते हैं।

0

वर्किंग_TABLE कितना बड़ा है? यदि यह काफी छोटा है, तो आप work_table से संग्रह में चयन करने का प्रयास कर सकते हैं, और फिर उस सूची के तत्वों को एक सूची में तत्वों के रूप में सहेज सकते हैं। zith प्रमुखता संकेत में

declare 
    TYPE t_type IS TABLE OF VARCHAR2(60); 
    v_coll t_type; 
begin 
    dbms_application_info.set_module('TEST','TEST'); 
    -- 
    select distinct object_type 
    bulk collect into v_coll 
    from user_objects; 
    -- 
    IF v_coll.count > 20 THEN 
    raise_application_error(-20001,'You need '||v_coll.count||' elements in the IN list'); 
    ELSE 
    v_coll.extend(20); 
    END IF; 
    insert into abc (object_type, object_name) 
    select object_type, object_name 
    from [email protected] 
    where object_type in 
      (v_coll(1), v_coll(2), v_coll(3), v_coll(4), v_coll(5), 
      v_coll(6), v_coll(7), v_coll(8), v_coll(9), v_coll(10), 
      v_coll(11), v_coll(12), v_coll(13), v_coll(14), v_coll(15), 
      v_coll(16), v_coll(17), v_coll(18), v_coll(19), v_coll(20) 
      ); 
    -- 
    dbms_output.put_line(sql%rowcount); 
end; 
/
+0

यह मेरा प्रारंभिक दृष्टिकोण था लेकिन कार्य तालिका में 1000 से अधिक तत्व हो सकते हैं। मुझे लगता है कि सीमाओं के साथ रहने के लिए मुझे 1000 के समूहों द्वारा प्रसंस्करण को तोड़ना होगा। – Domtar

+0

क्या आप लिंक के रिमोट साइड पर वैश्विक अस्थायी तालिका बनाने में सक्षम हैं? आप उस कार्य तालिका से उसमें सम्मिलित कर सकते हैं, फिर सभी शामिल रिमोट साइड पर होंगे। –

0

सम्मिलित 11,2

INSERT /*+ append */ 
     INTO MIG_CGD30_TEST  
       SELECT /*+ cardinality(ZFD 400000) cardinality(CGD 60000000)*/ 
      TRIM (CGD.NUMCPT) AS NUMCPT, TRIM (ZFD.NUMBDC_NEW) AS NUMBDC 
       FROM [email protected]_MIG_THALER CGD, 
        [email protected]_MIG_THALER ZFD, 
        EVD01_ADS_DR3W2 EVD 
1

में काम करने के लिए ओरेकल, डालने बयानों के लिए driving_site संकेत पर ध्यान नहीं देगा के रूप में DML हमेशा स्थानीय रूप से क्रियान्वित किया जाता रहा है। ऐसा करने का तरीका ड्राइविंग साइट संकेत के साथ एक कर्सर बनाना है, और उसके बाद कर्सर के माध्यम से कर्सर के माध्यम से एक bulkcollect/forall के साथ लूप और लक्ष्य स्थानीय तालिका में डालें।

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