sql >> Databasteknik >  >> RDS >> Oracle

SQL Loader, trigger saturation?

Du är redan halvvägs till lösningen:

Detta är ingen överraskning. Din nuvarande implementering exekverar många en rad SELECT-satser för varje rad du infogar i tabell B. Det kommer oundvikligen att ge dig en dålig prestandaprofil. SQL är ett uppsättningsbaserat språk och fungerar bättre med operationer med flera rader.

Så vad du behöver göra är att hitta ett sätt att ersätta alla SELECT-satser som är mer effektiva alternativ. Då kommer du att kunna släppa triggers permanent. Byt till exempel ut uppslagningarna i ordboken med främmande nycklar mellan tabell A-kolumnerna och referenstabellen. Relationella integritetsbegränsningar, eftersom de är intern Oracle-kod, presterar mycket bättre än någon kod vi kan skriva (och fungerar även i miljöer med flera användare).

Regeln om att inte infoga i tabell A om en kombination av kolumner redan finns i tabell B är mer problematisk. Inte för att det är svårt att göra utan för att det låter som dålig relationsdesign. Om du inte vill ladda poster i tabell A när de redan lämnas i tabell B, varför laddar du inte in i tabell B direkt? Eller så kanske du har en underuppsättning av kolumner som bör extraheras från tabell A och tabell B och formas till tabell C (som skulle ha främmande nyckelrelationer med A och B)?

Hur som helst, om du lämnar det åt ena sidan kan du göra detta med uppsättningsbaserad SQL genom att ersätta SQL*Loader med en extern tabell. En extern tabell låter oss presentera en CSV-fil för databasen som om det vore en vanlig tabell. Det betyder att vi kan använda det i vanliga SQL-satser. Läs mer.

Så med begränsningar för främmande nyckel i ordboken och en extern tabell kan du ersätta SQL Loader-koden med den här satsen (med förbehåll för vilka andra regler som är inordnade i "... och så vidare"):

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

Detta använder DML-felloggningssyntaxen för att fånga begränsningsfel för alla rader på ett uppsättningsbaserat sätt. Läs mer . Det kommer inte att skapa undantag för rader som redan finns i tabell B. Du kan antingen använda multitabellen INFOGA ALLA att dirigera rader till en spilltabell eller använda en MINUS-uppsättningsoperation efter händelsen för att hitta rader i den externa tabellen som inte finns i tabell A. Beror på ditt slutmål och hur du behöver rapportera saker.

Kanske ett mer komplicerat svar än du förväntade dig. Oracle SQL är en mycket omfattande SQL-implementering, med mycket funktionalitet för att effektivisera bulkoperationer. Det lönar sig verkligen att läsa konceptguiden och SQL-referensen för att ta reda på hur mycket vi kan göra med Oracle.




  1. Ta bort Oracle Data Provider för .NET från Global Assembly Cache

  2. Hur konverterar jag ett latitud/longitudpar till en PostGIS geografityp?

  3. Chef mysql opscode-kokböcker fungerar inte:kunde inte hitta recept rubin för kokbok mysql

  4. Kan jag använda en underfråga i en INSERT-sats?