sql >> Databáze >  >> RDS >> Oracle

SQL Loader, Trigger saturation?

Už jste na půli cesty k řešení:

To není překvapení. Vaše aktuální implementace provádí mnoho jednořádkových příkazů SELECT pro každý řádek, který vložíte do tabulky B. To nevyhnutelně povede ke špatnému profilu výkonu. SQL je jazyk založený na množinách a funguje lépe při víceřádkových operacích.

Takže, co musíte udělat, je najít způsob, jak nahradit všechny příkazy SELECT, které jsou efektivnějšími alternativami. Pak budete moci spouštěče trvale zrušit. Například nahraďte vyhledávání ve slovníku cizími klíči mezi sloupci tabulky A a referenční tabulkou. Omezení relační integrity, protože jde o interní kód Oracle, fungují mnohem lépe než jakýkoli kód, který můžeme napsat (a také pracovat v prostředí s více uživateli).

Problematičtější je pravidlo o nevkládání do tabulky A, pokud již v tabulce B existuje kombinace sloupců. Ne proto, že by to bylo těžké, ale proto, že to zní jako špatný vztahový design. Pokud nechcete načítat záznamy v tabulce A, když již opouštějí tabulku B, proč nenačítáte přímo do tabulky B? Nebo možná máte podmnožinu sloupců, které by měly být extrahovány z tabulky A a tabulka B a zformována do tabulky C (která by měla vztahy s cizím klíčem s A a B)?

Každopádně, když to necháme stranou, můžete to udělat pomocí SQL založeného na množinách nahrazením SQL*Loader externí tabulkou. Externí tabulka nám umožňuje prezentovat CSV soubor do databáze, jako by to byla běžná tabulka. To znamená, že jej můžeme použít v běžných příkazech SQL. Další informace

Takže s omezeními cizího klíče ve slovníku a externí tabulkou můžete nahradit kód SQL Loaderu tímto příkazem (s výhradou jakýchkoli dalších pravidel, která jsou zahrnuta do "...a tak dále"):

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

To využívá syntaxi protokolování chyb DML k zachycení chyb omezení pro všechny řádky způsobem založeným na množinách. Další informace . Nevyvolá výjimky pro řádky, které již v tabulce B existují. Můžete použít vícetabulkový INSERT ALL směrovat řádky do přetékající tabulky nebo použít operaci MINUS set po události k nalezení řádků v externí tabulce, které nejsou v tabulce A. Záleží na vašem konečném cíli a na tom, jak potřebujete věci hlásit.

Možná složitější odpověď, než jste čekali. Oracle SQL je velmi rozsáhlá implementace SQL se spoustou funkcí pro zlepšení efektivity hromadných operací. Opravdu se nám vyplatí přečíst si Concepts Guide a SQL Reference, abychom zjistili, kolik toho můžeme s Oracle dělat.




  1. Mohu použít výjimky ve smyčce FOR LOOP k vynucení pokračování při chybě?

  2. Doporučené postupy pro měkké odstranění (PHP/MySQL)

  3. Hibernate:Použití dvou různých schémat databáze ve stejné aplikaci

  4. Jak vybrat pomocí binárního pole? (php,mysql)