0
votes

Tonge de performance de curseur imbriquée

J'ai 2 curseurs, une pour récupérer des enregistrements d'une table de 50 colonnes et 10 000 + données et une autre pour vérifier si une colonne particulière existe dans une autre grande table (2 millions de données). Je devrais écrire dans un fichier tous les enregistrements du curseur 1 pendant un an, si cette colonne existe dans le curseur 2, je devrais imprimer un message d'erreur comme il existe et ne les supprimez pas. Si cela n'existe pas, je devrais supprimer la ligne et l'écrire au même fichier et le même message que l'enregistrement supprimé. J'ai utilisé un curseur imbriqué, la performance est trop mauvaise car elle traite chaque rangée du curseur 1 contre le curseur 2, à chaque fois.

       CURSOR cursor1
         IS           
             select a.* ,a.rowid
              FROM table1 a 
              WHERE a.table1.year = p_year;
    
    CURSOR check_c2(lv_cd )
     IS
      Select DISTINCT 'Y' 
       from table2
       where table2 ='R'
       AND table2.year= p_year
       and table2_code= lv_cd ;

BEGIN :
   FOR r in cursor1 LOOP
            EXIT WHEN cursor1%NOTFOUND;
        
              OPEN check_c2(r.cd);
              FETCH check_c2 INTO lv_check;
                IF check_c2%NOTFOUND THEN
                    lv_check :='N';
                END IF;
                CLOSE check_c2;
       
                  IF lv_check ='Y' THEN
                   lv_msg =(r.col1,r.col2....r.col50, R code exists do not delete)
                   utl_file.put_line(lv_log_file, lv_msg, autoflush=>TRUE);
                   
                ELSE 
                  DELETE from table1 where rowid= r.rowid
                  lv_msg =(r.col1,r.col2....r.col50, delete row)
                   utl_file.put_line(lv_log_file, lv_msg, autoflush=>TRUE);
                   END IF;
                   END LOOP;


0 commentaires

3 Réponses :


0
votes

Et ça? Une opération de 3 étapes:

Étape 1: "Enregistrer" des lignes Vous allez supprimer ultérieurement P>

delete from table1 a
where exists (select null
              from table2 b
              where b.year = a.year
                and b.code = a.code
             );


1 commentaires

Donc, comme le stocker dans une table Temp. J'ai peur de ne pas pouvoir le faire.



0
votes

utl_file.put_line dans la boucle sera un ax-tête. Élatrices Ajout à LV_MSG jusqu'à la longueur de la chaîne est de 32767 octets et écrivez une seule fois. Cela réduira certainement l'E / S et la performance devraient être améliorés.


3 commentaires

Devrais-je ajouter ul_file.put_line au lieu d'y écrire?


Vous ne voudriez pas couper lv_msg pour un record au milieu. Continuez à ajouter à LV_MSG avec une nouvelle ligne (CHR (10)) et lorsque la longueur est inférieure à 32767, écrivez au fichier et réinitialiser LV_MSG à NULL.


J'ai essayé cela, la performance n'était meilleure que de quelques minutes. Merci



1
votes

ne pas avoir assez de réputation pour écrire des commentaires som écrira comme une réponse.

Vous n'avez pas essayé d'ajouter des marques de temps pour comprendre quelles parties sont les pièces les plus chères? P>

TABLEA2 a-t-il index par année et code? Quel est le plan explique de la requête CURSOR2? Si oui - combien de lignes y a-t-il une moyenne pour une combinaison d'année + du code? Si la quantité de données sélectionnée dans l'ensemble du tableau 2 est énorme - alors elle peut probablement être plus rapide de faire une seule requête avec une analyse complète de la plage de balayage / index par année sur la table2, le regroupement et la jointure extérieure gauche de la table1 à la table2 de Tableau. >

select a.*, a.rowid, nvl2(c.code, 'Y', 'N') check_col
from table1 a,
(
    select distinct code
    from table2 b
    where b.year = p_year
) c
where a.year = p_year
  and c.code(+) = a.cd


3 commentaires

@Doranaveut j'ai essayé une requête unique, la performance est bien meilleure qu'auparavant. Merci


@Doranaveut - Quand j'ai essayé d'ajouter plus de conditions au tableau1 A, il continue à courir pour toujours. Je viens d'utiliser et avant la jointure pour ajouter les conditions


@arsha a des conditions supplémentaires pourraient changer le plan d'exécution. Le texte de la requête et le plan d'exécution sont nécessaires au moins pour dire quoi que ce soit.