Ya estás a medio camino de la solución:
Esto no es una sorpresa. Su implementación actual ejecuta muchas declaraciones SELECT de una sola fila para cada fila que inserta en la tabla B. Eso inevitablemente le dará un perfil de rendimiento deficiente. SQL es un lenguaje basado en conjuntos y funciona mejor con operaciones de varias filas.
Entonces, lo que debe hacer es encontrar una manera de reemplazar todas las declaraciones SELECT con alternativas más eficientes. Entonces podrás soltar los desencadenantes de forma permanente. Por ejemplo, reemplace las búsquedas en el diccionario con claves externas entre las columnas de la tabla A y la tabla de referencia. Las restricciones de integridad relacional, al ser un código interno de Oracle, funcionan mucho mejor que cualquier código que podamos escribir (y también funcionan en entornos multiusuario).
La regla de no insertar en la tabla A si ya existe una combinación de columnas en la tabla B es más problemática. No porque sea difícil de hacer, sino porque suena como un diseño relacional deficiente. Si no desea cargar registros en la tabla A cuando ya están en la tabla B, ¿por qué no está cargando directamente en la tabla B? O quizás tenga un subconjunto de columnas que debería extraerse de la tabla A y tabla B y se formó en la tabla C (que tendría relaciones de clave externa con A y B)?
De todos modos, dejando eso a un lado, puede hacer esto con SQL basado en conjuntos reemplazando SQL*Loader con una tabla externa. Una tabla externa nos permite presentar un archivo CSV a la base de datos como si fuera una tabla normal. Esto significa que podemos usarlo en sentencias SQL normales. Más información
Por lo tanto, con restricciones de clave externa en el diccionario y una tabla externa, puede reemplazar el código del cargador SQL con esta declaración (sujeto a cualquier otra regla incluida en "... y así sucesivamente"):
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') ;
Esto emplea la sintaxis de registro de errores de DML para capturar errores de restricción para todas las filas en una forma basada en conjuntos. Más información . No generará excepciones para las filas que ya existen en la tabla B. Puede usar la tabla múltiple INSERTAR TODO para enrutar filas a una tabla de desbordamiento o usar una operación de configuración MENOS después del evento para encontrar filas en la tabla externa que no están en la tabla A. Depende de su objetivo final y de cómo necesita informar las cosas.
Quizás una respuesta más compleja de lo que esperabas. Oracle SQL es una implementación de SQL muy extensa, con mucha funcionalidad para mejorar la eficiencia de las operaciones masivas. Realmente vale la pena leer la Guía de conceptos y la Referencia de SQL para descubrir cuánto podemos hacer con Oracle.