Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

SQL Loader, saturação do gatilho?


Você já está a meio caminho da solução:

Isso não é uma surpresa. Sua implementação atual executa muitas instruções SELECT de linha única para cada linha inserida na tabela B. Isso inevitavelmente resultará em um perfil de desempenho ruim. SQL é uma linguagem baseada em conjunto e funciona melhor com operações de várias linhas.

Então, o que você precisa fazer é encontrar uma maneira de substituir todas as instruções SELECT por alternativas mais eficientes. Então você poderá soltar os gatilhos permanentemente. Por exemplo, substitua as pesquisas no dicionário por chaves estrangeiras entre as colunas da tabela A e a tabela de referência. As restrições de integridade relacional, sendo código interno da Oracle, têm um desempenho muito melhor do que qualquer código que possamos escrever (e também funcionam em ambientes multiusuário).

A regra de não inserir na tabela A se já existir uma combinação de colunas na tabela B é mais problemática. Não porque seja difícil de fazer, mas porque soa como um design relacional ruim. Se você não deseja carregar registros na tabela A quando eles já estão na tabela B, por que você não está carregando diretamente na tabela B? Ou talvez você tenha um subconjunto de colunas que deve ser extraído da tabela A e tabela B e formado na tabela C (que teria relações de chave estrangeira com A e B)?

De qualquer forma, deixando isso de lado, você pode fazer isso com SQL baseado em conjunto substituindo SQL*Loader por uma tabela externa. Uma tabela externa nos permite apresentar um arquivo CSV ao banco de dados como se fosse uma tabela normal. Isso significa que podemos usá-lo em instruções SQL normais. Saiba mais.

Portanto, com restrições de chave estrangeira no dicionário e uma tabela externa, você pode substituir o código do SQL Loader por esta instrução (sujeito a quaisquer outras regras incluídas em "... e assim por diante"):
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') ;

Isso emprega a sintaxe de registro de erros DML para capturar erros de restrição para todas as linhas de maneira baseada em conjunto. Saiba mais . Ele não gerará exceções para linhas que já existem na tabela B. Você pode usar a multi-tabela INSERT ALL para rotear linhas em uma tabela de estouro ou usar uma operação de conjunto MINUS após o evento para localizar linhas na tabela externa que não estão na tabela A. Depende do seu objetivo final e de como você precisa relatar as coisas.

Talvez uma resposta mais complexa do que você esperava. O Oracle SQL é uma implementação de SQL muito extensa, com muitas funcionalidades para melhorar a eficiência das operações em massa. Realmente vale a pena ler o Guia de Conceitos e a Referência SQL para descobrir o quanto podemos fazer com o Oracle.