sql >> Database >  >> RDS >> Oracle

SQL Loader, verzadiging triggeren?

Je bent al halverwege de oplossing:

Dit is geen verrassing. Uw huidige implementatie voert veel enkele rij SELECT-instructies uit voor elke rij die u in tabel B invoegt. Dat zal u onvermijdelijk een slecht prestatieprofiel opleveren. SQL is een op een set gebaseerde taal en presteert beter bij bewerkingen met meerdere rijen.

Dus wat u moet doen, is een manier vinden om alle SELECT-instructies te vervangen die efficiëntere alternatieven zijn. Dan kun je de triggers permanent laten vallen. Vervang bijvoorbeeld de opzoekingen in het woordenboek door externe sleutels tussen de tabel A-kolommen en de referentietabel. Relationele integriteitsbeperkingen, die interne Oracle-code zijn, presteren veel beter dan welke code dan ook die we kunnen schrijven (en werken ook in omgevingen met meerdere gebruikers).

De regel over het niet invoegen in tabel A als er al een combinatie van kolommen in tabel B bestaat, is problematischer. Niet omdat het moeilijk is om te doen, maar omdat het klinkt als een slecht relationeel ontwerp. Als u geen records in tabel A wilt laden wanneer ze al in tabel B worden verlaten, waarom laadt u dan niet rechtstreeks in tabel B? Of misschien heeft u een subset van kolommen die uit tabel A moeten worden gehaald en tabel B en gevormd tot tabel C (die relaties met externe sleutels zou hebben met A en B)?

Hoe dan ook, laat dat terzijde, je kunt dit doen met set-gebaseerde SQL door SQL*Loader te vervangen door een externe tabel. Met een externe tabel kunnen we een CSV-bestand aan de database presenteren alsof het een gewone tabel is. Dit betekent dat we het kunnen gebruiken in normale SQL-instructies. Meer informatie.

Dus, met beperkingen voor externe sleutels op het woordenboek en een externe tabel, kunt u de SQL Loader-code vervangen door deze instructie (afhankelijk van de andere regels die zijn ondergebracht in "... enzovoort"):

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

Dit maakt gebruik van de DML-syntaxis voor foutregistratie om beperkingsfouten voor alle rijen op een set-gebaseerde manier vast te leggen. Meer informatie . Er worden geen uitzonderingen gegenereerd voor rijen die al in tabel B staan. U kunt ofwel de multi-table INSERT ALL om rijen naar een overlooptabel te routeren of gebruik een MIN-setbewerking na de gebeurtenis om rijen in de externe tabel te vinden die niet in tabel A staan. Hangt af van uw einddoel en hoe u dingen moet melden.

Misschien een complexer antwoord dan je had verwacht. Oracle SQL is een zeer uitgebreide SQL-implementatie, met veel functionaliteit voor het efficiënter maken van bulkoperaties. Het loont echt de moeite om de Concepts Guide en de SQL Reference te lezen om erachter te komen hoeveel we met Oracle kunnen doen.




  1. Eén quizitem per pagina (php/mysql-quizprogramma)

  2. Python SQLAlchemy Query:AttributeError:'Connection'-object heeft geen attribuut 'contextual_connect'

  3. Maak een tabel in door sql-instructie met behulp van executeUpdate in Mysql

  4. Verbindingsbeheer in PostgreSQL:een gids