terça-feira, agosto 20, 2013

Create e Update utilizando Integration Services

Uma funcionalidade comum quando se utilizam os Integration Services é a copia de informação de uma tabela para outra. Acontece que o habitual é existir algo que me controle a importação de informação (tabela auxiliar, coluna da tabela a importar, contador, identity, etc), e que me permita saber a partir de que linha preciso retomar a importação pois as anteriores já foram importadas.

Agora existe um problema, como vou lidar com as linhas que já importei previamente, mas que têm valores modificados na tabela de origem? A resolução tradicional para este problema, e que pode ser encontrada em vários posts é a seguinte:
Vamos obter as linhas da tabela base, fazemos um lookup para verificar se a tabela destino já contem a linha, e decidimos então se a linha é para inserir ou para actualizar. Isto acaba por não ser muito penalizador se estivermos a falar de 10.000, 20.000, 50.000 ou até 100.000 linhas, o problema é quando começamos a falar de centenas de milhares de linhas ou mais. 

Enquanto que o processo de inserção funciona com bulks, ou seja, são inseridos blocos de linhas, no caso da caixa marcada a vermelho na imagem anterior as actualizações, estas são feitas uma a uma, o que permitirá inserir valores a rondar as 500-600 linhas por minuto. Já se começa a perceber o problema desta solução, então o objectivo é eliminar o update e substitui-lo por algo diferente.

Então cheguei à solução seguinte, que tem um desempenho muito, mas muito superior:

A alteração principal é a utilização de uma tabela auxiliar que é exactamente igual à tabela principal e agora o processo é extremamente simples.
1) Copiar todas as linhas sejam novas, sejam para actualizar, para a tabela auxiliar
2) Eliminar todas as linhas da tabela principal (utilizando as suas keys), que iriam ser alvo de actualizações
3) Copiar todas as linhas da tabela auxiliar para a tabela principal
4) Apagar todas as linhas da tabela auxiliar, deixando-a pronta para uma nova execução.

Sem comentários: