Oracle
 sql >> Base de données >  >> RDS >> Oracle

SQL Loader, Saturation du déclencheur ?

Vous êtes déjà à mi-chemin de la solution :

Ce n'est pas une surprise. Votre implémentation actuelle exécute un grand nombre d'instructions SELECT sur une seule ligne pour chaque ligne que vous insérez dans la table B. Cela vous donnera inévitablement un profil de performances médiocre. SQL est un langage basé sur des ensembles et fonctionne mieux avec les opérations sur plusieurs lignes.

Donc, ce que vous devez faire est de trouver un moyen de remplacer toutes les instructions SELECT par des alternatives plus efficaces. Ensuite, vous pourrez supprimer les déclencheurs de manière permanente. Par exemple, remplacez les recherches sur le dictionnaire par des clés étrangères entre les colonnes de la table A et la table de référence. Les contraintes d'intégrité relationnelle, étant du code Oracle interne, fonctionnent bien mieux que n'importe quel code que nous pouvons écrire (et fonctionnent également dans des environnements multi-utilisateurs).

La règle de ne pas insérer dans la table A si une combinaison de colonnes existe déjà dans la table B est plus problématique. Non pas parce que c'est difficile à faire, mais parce que cela ressemble à une mauvaise conception relationnelle. Si vous ne voulez pas charger les enregistrements dans la table A alors qu'ils existent déjà dans la table B, pourquoi ne les chargez-vous pas directement dans la table B ? Ou peut-être avez-vous un sous-ensemble de colonnes qui doivent être extraites de la table A et table B et formé dans la table C (qui aurait des relations de clé étrangère avec A et B) ?

Quoi qu'il en soit, en laissant cela de côté, vous pouvez le faire avec du SQL basé sur des ensembles en remplaçant SQL*Loader par une table externe. Une table externe nous permet de présenter un fichier CSV à la base de données comme s'il s'agissait d'une table normale. Cela signifie que nous pouvons l'utiliser dans des instructions SQL normales. En savoir plus.

Ainsi, avec des contraintes de clé étrangère sur le dictionnaire et une table externe, vous pouvez remplacer le code SQL Loader par cette instruction (sous réserve de toutes les autres règles incluses dans "... et ainsi de suite") :

insert into table_a
select ext.* 
from external_table ext
     left outer join table_b b
     on (ext.name = b.name and ext.last_name = b.last_name and ext.dept=b.dept)
where b.name is null
log errors into err_table_a ('load_fail') ;

Cela utilise la syntaxe de journalisation des erreurs DML pour capturer les erreurs de contrainte pour toutes les lignes d'une manière basée sur un ensemble. En savoir plus . Il ne déclenchera pas d'exceptions pour les lignes qui existent déjà dans la table B. Vous pouvez soit utiliser le multi-table INSERT ALL pour acheminer des lignes dans une table de débordement ou utiliser une opération d'ensemble MINUS après l'événement pour rechercher des lignes dans la table externe qui ne sont pas dans la table A. Cela dépend de votre objectif final et de la manière dont vous devez signaler les choses.

Peut-être une réponse plus complexe que ce à quoi vous vous attendiez. Oracle SQL est une implémentation SQL très complète, avec de nombreuses fonctionnalités pour améliorer l'efficacité des opérations en bloc. Cela nous rapporte vraiment de lire le Guide des concepts et la référence SQL pour découvrir tout ce que nous pouvons faire avec Oracle.