9
votes

Sélectionnez et insérez sur Dblink

J'ai un peu de problème avec un élément de sélection dans un insert sur un dblink à Oracle 10. J'utilise l'instruction suivante:

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


0 commentaires

6 Réponses :


3
votes

Vous voudrez peut-être utiliser l'indice HORD_SITE. Il y a une bonne explication ici: http://www.dba-oracle.com/t_sql_dblink_performance.htm


1 commentaires

J'avais essayé d'ajouter l'indice suivant à la requête initiale avant de poster mais obtenez les mêmes résultats. / * + Driving_Site (s) * / QUI CONSERVEZ CONDUITER LE SIDE DLINK CORRECT?



2
votes

Tirer parti de la clause avec peut optimiser votre récupération de votre ensemble de travail:

WITH remote_rows AS
     (SELECT /*+DRIVING_SITE(s)*/COL1, COL2
      FROM REMOTE.TABLE1@dblink s
      WHERE COL1 IN ( SELECT COL1 FROM WORKING_TABLE)) 
INSERT INTO LOCAL.TABLE_1 ( COL1, COL2)
SELECT  COL1, COL2
FROM remote_rows


1 commentaires

Cette réponse montre que votre syntaxe n'est pas correcte.



3
votes

En ce qui concerne la DML, Oracle choisit d'ignorer tout indice Drivoul_Site et exécute la déclaration sur le site cible. Je doute donc si vous pouviez changer cela (même en utilisant avec une approche décrite ci-dessus). Une solution possible est que vous pouvez créer un synonyme de local.Table1 sur la base de données distante et utilisez la même chose dans votre instruction insertion.


0 commentaires

0
votes

Quelle est la taille du travail_table? Si elle est assez petite, vous pouvez essayer de sélectionner de Work_Table dans une collection, puis de transmettre les éléments de ceux qui collectent en tant qu'éléments dans une liste dans une liste.

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 user_objects@tmfprd
  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;
/


2 commentaires

C'était mon approche initiale, mais il peut y avoir plus de 1000 éléments dans la table de travail. Je pense que je devrai briser la transformation par des groupes de 1000 pour rester avec le lieu où dans les limites.


Êtes-vous capable de créer une table temporaire globale sur le côté distant du lien? Vous pouvez insérer dans cela de la table de travail, puis la jointure serait toutes du côté distant.



0
votes

Insérer dans ZIT CARDINALITY CONSEIGNE semble fonctionner dans 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 CGD30@DBL_MIG_THALER CGD,
                   ZFD10@DBL_MIG_THALER ZFD,
                   EVD01_ADS_DR3W2  EVD


0 commentaires

2
votes

Oracle ignorera l'indice HautT_Site pour insérer des instructions, car DML est toujours exécuté localement. La manière de le faire consiste à créer un curseur avec l'indice de sites d'entraînement, puis boucle à travers le curseur avec un moulage avec un moulage et une explosion et une insérer dans la table locale cible.


0 commentaires