October 30, 2008

História de pescador - parte 2

Filed under: postgresql — coutinho @ 12:00 am

Outra coisa interessante que ocorreu na migração da base de dados do Detran foi quando tivemos que migrar uma rotina que importava uns dados vindos de um Main Frame. Um arquivo em formato texto plano com uns 800 mil registros.

O detalhe interessante é que não havia um delimitador de campo. Os registros eram o que muita gente chamada de “tripa” de tamanho fixo. Um regostro lá era mais ou menos assim:

00001232000000023ANTONIO LUIZ DE EXEMPLO SILVARUA ALMERINDA DE EXEMPLO SILVA230320089874561239876567SSPRJ100001

Tempo Total do Processo usando Oracle: 2 Horas

Como o pessoal do oracle tratava isso? Eles usavam um recurso que permite que isso seja vinculado ao oracle como uma tabela, no DDL usada para fazer essa operação o usuário ou DBA pode mapear os campos dizendo o inicio e tamanho de cada campo. Após isso eles copiavam esses dados para outras tabelas usando selects.

Como o pessoal do PostgreSQL (equipe da Mondrian Tecnologia) tratou isso?

Fizemos uma função usando plpython que transformou o tal arquivo em um csv e a nossa linha de exemplo ficou mais menos assim:

“00001232″,”000000023″,”ANTONIO LUIZ DE EXEMPLO SILVA”,”RUA ALMERINDA DE EXEMPLO SILVA”,”2303200″,”8987456123″,”9876567″,”SSPRJ”,”10000″,”1″

Após isso nossa função executa um copy desse arquivo para uma tabela real do PostgreSQL onde o acesso é bem mais rápido que a uma tabela vinculada do oracle como na situação anterior, a partir daí copiamos os dados necessários para as demais tabelas também usando copy.

Tempo Total do Processo usando o estilo PostgreSQL de ser: 6 min

4 Comments »

  1. Coutinho, tem alguma coisa errada neße tempo de 2h para o Oracle. Não querendo defendê-lo, mas o SQL*Loader (que está por trás do mecanismo de tabela externa que você descreveu) não é exatamente uma tartaruga. Algum problema de configuração ou uso, talvez…

    Ißo dito, é bom ver o Elefante Azul batendo no Oráculo!

    Comment by Leandro Guimarães Faria Corcete DUTRA — October 30, 2008 @ 1:36 pm

  2. Cara, ainda participei com a equipe da Mondrian por alguns dias e vi o trabalho de vocês, em destaque o seu, Coutinho.
    Cara, meus sinceros parabéns, pois vocês foram uns monstros. Fizeram um grande trabalho na migração do DETRAN do Oracle para o PostgreSQL.

    Parabéns!

    Comment by Ribamar FS — October 30, 2008 @ 3:40 pm

  3. Oi Leandro, eu não disse que o Loader é uma tartaruga, mas ele é mais lento que uma tabela convecional. O problema era o restante do processo que copiava dados dessa tabela para outra usando select, e depois para outras e outras.

    Só para você ter uma idéia, migrando isso para o PostgreSQL, e eliminar e substituir o loader pelo copy não resolver o problema pois após isso o processo levou 8 horas no postgreSQL e ainda não havia chegado ao fim, foi aí que vimos que teríamos que re-escrever a função.

    Acredito que rescrevendo o procedimento do Oracle a gente gonseguiria também reduzi-lo a minutos.

    O problema como você falou era mesmo o uso. Ex:

    O cara poderia ter usado o loader para carregar de uma vez os dados para uma tabela real do Oracle. Ao invés disso ele deixou uma tabela linkada ao arquivo que ele deveria ter importado e depois continuava fazendo vários select nessa tabela.

    Isso no postgreSQL ficou bem lento, então nós utilizamos o copy para levar os dados às outras tabelas. Foi nesse ponto onde ganhamos muito. No oracle eles faziam essa copia com select (com copy seria ficou mais rápido) e a partir de uma tabela que não é das mais rápidas.

    Era algo mais ou menos assim:

    a - tabela vinculada (mais lenta que uma tabela normal)
    b - tabela real
    c - tabela real

    truncate c;
    select * from b into c;
    truncate b;
    select * from a into b;
    insert into z select * from a where x = yyy;

    No postgreSQL

    a - tabela real
    b - tabela real
    c - tabela real

    funcao python quebrava o arquivo e gerava o arquivo /tmp/a para ser importado via copy para a tabela física a

    copy a from ‘/tmp/a’
    truncate c;
    copy b to ‘/tmp/b’;
    copy c from ‘/tmp/b’;
    truncate b;
    copy c from ‘/tmp/a’;

    Comment by coutinho — October 30, 2008 @ 9:43 pm

  4. Parabéns cara, ótimo site !
    Eu tb fiz um loader nesse estilo, foi para o NetFlix Prize, e ele é violento, são 150 milhões de registros na “tripa” e pior ainda, é em multiplos arquivos com identificador de tipo de registro na linha.
    O PL/PgSql com copy segurou a bomba numa boa, rodou no limite do harddisk a 150mb/s, e em poucos minutos eu tive as tabelas prontas e indexadas.
    Postgres é tudo di bom !
    Abraços !

    Comment by Hamilton R. Amorim — June 23, 2009 @ 3:52 pm

RSS feed for comments on this post. TrackBack URI

Leave a comment