Oracle
 sql >> Database >  >> RDS >> Oracle

Caricatore SQL, saturazione trigger?

Sei già a metà strada verso la soluzione:

Questa non è una sorpresa. La tua attuale implementazione esegue molte istruzioni SELECT a riga singola per ogni riga inserita nella tabella B. Ciò ti darà inevitabilmente un profilo di prestazioni scadente. SQL è un linguaggio basato su insiemi e offre prestazioni migliori con operazioni su più righe.

Quindi, quello che devi fare è trovare un modo per sostituire tutte le istruzioni SELECT quali alternative più efficienti. Quindi sarai in grado di rilasciare i trigger in modo permanente. Ad esempio, sostituisci le ricerche sul dizionario con chiavi esterne tra le colonne della tabella A e la tabella di riferimento. I vincoli di integrità relazionale, essendo codice Oracle interno, funzionano molto meglio di qualsiasi codice che possiamo scrivere (e funzionano anche in ambienti multiutente).

La regola di non inserire nella tabella A se esiste già una combinazione di colonne nella tabella B è più problematica. Non perché sia ​​difficile da fare, ma perché suona come un design relazionale scadente. Se non vuoi caricare i record nella tabella A quando escono già nella tabella B, perché non carichi direttamente nella tabella B? O forse hai un sottoinsieme di colonne che dovrebbero essere estratte dalla tabella A e tabella B e formata nella tabella C (che avrebbe relazioni di chiave esterna con A e B)?

Ad ogni modo, lasciandolo da parte, puoi farlo con SQL basato su set sostituendo SQL*Loader con una tabella esterna. Una tabella esterna ci permette di presentare un file CSV al database come se fosse una tabella normale. Ciò significa che possiamo usarlo nelle normali istruzioni SQL. Scopri di più.

Quindi, con i vincoli di chiave esterna sul dizionario e una tabella esterna puoi sostituire il codice SQL Loader con questa istruzione (soggetto a qualsiasi altra regola sia inclusa in "... e così via"):

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') ;

Ciò utilizza la sintassi di registrazione degli errori DML per acquisire gli errori di vincolo per tutte le righe in base a un set. Scopri di più . Non solleverà eccezioni per righe già esistenti nella tabella B. Puoi utilizzare la multitabella INSERT ALL per instradare le righe in una tabella di overflow o utilizzare un'operazione di impostazione MINUS dopo l'evento per trovare righe nella tabella esterna che non sono nella tabella A. Dipende dall'obiettivo finale e da come è necessario segnalare le cose.

Forse una risposta più complessa di quanto ti aspettassi. Oracle SQL è un'implementazione SQL molto estesa, con molte funzionalità per migliorare l'efficienza delle operazioni di massa. Ci ripaga davvero leggere la Guida ai concetti e il Riferimento SQL per scoprire quanto possiamo fare con Oracle.