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;
3 Réponses :
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 );
Donc, comme le stocker dans une table Temp. J'ai peur de ne pas pouvoir le faire.
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. P>
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
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
@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.