Alternativas para comparar dados de diferentes bancos de dados

5

Eu tenho duas tabelas enormes em bancos de dados separados. Um deles tem as informações de todos os SMS que passaram pelos servidores da empresa enquanto o outro tem as informações do faturamento real desses SMS.

Meu trabalho é comparar amostras de ambas as tabelas (por exemplo, os registros entre 1 e 2 da tarde) para ver se há alguma diferença: SMS que foram enviados mas não cobrados do usuário por qualquer motivo que possa ser acontecendo.

As colunas que eu usarei para comparar são o número de telefone do remetente e a data exata em que o SMS foi enviado. Um problema aqui é que as datas geralmente são as mesmas em ambos os lados, mas em muitos casos diferem em 1 ou 2 segundos.

Eu tenho até agora duas alternativas para fazer isso:

  1. (PL / SQL) Crie duas tabelas onde armazenarei temporariamente todos os registros dessa amostra de 1 hora. Um para cada uma das tabelas principais. Então, para cada número de telefone distinto, selecione a hora de cada SMS enviado daquele telefone de minhas duas tabelas temporárias e comece a comparar um por um usando os cursores. Nesse caso, o procedimento seria executado no servidor em que uma das fontes é, portanto, o conteúdo da outra seria pesquisado usando dblink.

  2. (sqlplus + c ++) Em vez de armazenar as amostras de 1 hora em novas tabelas, envie a consulta para um arquivo de texto. Eu vou ter dois arquivos de texto, um para cada fonte. Em seguida, abra o primeiro arquivo e carregue todo o conteúdo em um hash_map (valor-chave) usando c ++, em que a chave será o número de telefone e o valor uma lista de horas de SMS enviadas daquele telefone. Finalmente, abra o segundo arquivo, pegue cada linha (neste formato: numberX timeX), procure a entrada de numberX no hash_map (que será uma lista de vezes) e então verifique se timeX está nessa lista. Se não estiver, salve-o em algum lugar para finalmente armazená-lo em uma tabela "não carregada" (essa também seria a etapa final no caso 1)

Minha principal preocupação é a eficiência. Essas amostras têm cerca de 2 milhões de registros em cada fonte, então apenas pegar um registro de um lado e procurar o outro não seria possível. Essa é a razão pela qual eu queria usar hash_maps

Qual você acha que é uma opção melhor?

    
por Alex 01.06.2012 / 20:12
fonte

5 respostas

1

Se os bancos de dados estiverem no mesmo servidor, você pode simplesmente executar uma consulta nos dois bases de dados .

Se não, você pode usar Oracle Database Gateways (se tiver) para se conectar para ambos, e da mesma forma fazer a comparação.

    
por 01.06.2012 / 20:31
fonte
1

À primeira vista, sua segunda opção provavelmente será superior.
Aqui está minha linha de pensamento e suposições.

0) Eu estou supondo que você não tem um sistema de banco de dados enorme sentado à espera de uma consulta como esta para justificar o seu propósito.

1) É provável que você tenha executado isso várias vezes. Se nada mais, uma vez que as discrepâncias no processamento da fatura foram resolvidas, este processo de auditoria será necessário para validar as correções.

2) As operações paralelas serão fundamentais para obter tempos de execução razoáveis. A segunda opção que você sugere permitirá que você divida em pedaços de listas "enviadas" individuais e mapeamentos "faturados". Esses blocos podem ser distribuídos para clientes distribuídos para um tempo de processamento mais rápido.

3) O código C ++ fornecerá mais opções para lidar com as discrepâncias de tempo e o (re) processamento subseqüente dessas entradas.

    
por 01.06.2012 / 23:16
fonte
1

Aqui está uma maneira muito eficiente de comparar duas consultas (solução generalizada para o problema de comparar duas tabelas de maneira eficiente):

SELECT * FROM
(
  SELECT foo1 col1, foo2 col2 FROM ...
  UNION ALL
  SELECT bar1 col1, bar2 col2 FROM ...
) t
GROUP BY col1, col2
HAVING COUNT(*) = 1

Essa consulta usa duas subconsultas que devem ser idênticas e a saída são as linhas que estão apenas em uma das consultas. Em outras palavras, se as duas subconsultas retornarem linhas idênticas, a saída deverá estar vazia.

Eu precisava comparar dois grandes conjuntos de dados no passado, em que o desempenho era uma preocupação importante, e esse foi, de longe, o método mais rápido que encontrei.

Você mencionou que os timestamps podem ter alguns segundos de diferença. Para esconder esse ruído, eu recomendo usar algum tipo de arredondamento de data, mas eu não sei a sintaxe para isso.

    
por 01.06.2012 / 22:09
fonte
0

Dois milhões de registros não devem ser tão grandes, especialmente se o número de telefone for indexado. Então, o seu tempo é provavelmente mais importante que o tempo de consulta. Obviamente, eu provavelmente criaria uma tabela e importaria todos os registros de um banco de dados para outro se eu não pudesse referenciar os dois em uma consulta.

Então, suponho que você possa fazer referência a ambas as tabelas em uma consulta.

A lógica para correspondência na janela de 2 segundos é um pouco complicada. Por exemplo, e se houvesse um SMS às 12:00:01 e 12:00:05 e uma fatura para 12:00:03? Realmente, um dos dois não foi anunciado.

Então, o que você realmente quer como primeiro passo é combinar a contagem de mensagens SMS e as mensagens cobradas por um número de telefone. Mais tarde, você pode descobrir qual não foi faturado (ou possivelmente não ter informações suficientes para fazê-lo com precisão, como no meu exemplo).

Podemos fazer isso:

SELECT A.PhoneNumber,SentCount,BilledCount 
FROM 
     (SELECT SentMessages.PhoneNumber, Count(SentMessages.SentDate) as SentCount
        FROM SentMessage
    GROUP BY SentMessages.PhoneNumber) as A JOIN
      (SELECT BilledMessages.PhoneNumber, Count(BilledMessages.BilledDate) as BilledCount
        FROM BilledMessages
    GROUP BY BilledMessages.PhoneNumber) AS B
          ON A.PhoneNumber=B.PhoneNumber
       WHERE SentCount>BilledCount

E podemos também executar isso em toda a tabela como uma amostra - exceto que talvez algumas mensagens não devam ter sido faturadas ainda, então não queremos isso. Isso está fora do escopo da questão, de qualquer forma.

    
por 01.06.2012 / 23:15
fonte
0

Eu sugiro criar um link de banco de dados entre os dois bancos de dados, ele permite que você acesse uma tabela remota como se estivesse no mesmo banco de dados.

Depois de ter o link do banco de dados, codifique a solução em um procedimento de armazenamento de PL / SQL.

Sugiro PL / SQL Developer como o IDE para o procedimento de gravação.

    
por 24.08.2012 / 22:36
fonte