Pesquisar

Quem sou eu

Minha foto
Formado em Tecnologia de Processamento de Dados pela FESP-Paraná. Pós-graduado em Administração em Informática e Administração de Banco de Dados pela FESP-Paraná. Certificação ORACLE/OCA e DB2 9 Family Fundamentals.

segunda-feira, 24 de maio de 2010

COMO MELHORAR A PERFORMANCE DE INSERT

Olá !

Durante este mês, passei alguns dias analisando um problema de performance que ocorreu em uma das rotinas de fechamento mensal da aplicação de um de meus clientes. O problema era o seguinte: durante a rotina, um dos programas executa uma série de INSERTS com SELECT FULL dos dados das tabelas origem para outras tabelas da aplicação. Isto é feito mensalmente desde (aguarde um minuto pois estou pegando o MIN de uma data da tabela ... hehehe) o mês 5/2006. Duas destas tabelas tem uma média de 2 milhões de registros/mês. Ou seja, após quase 4 anos, a tabela que armazena uma cópia mensal destes dados acumulou mais de 100 milhões de registros. Juntem a isso, mas 3 índices criados para acesso aos dados destas tabelas ... Como diria Milton Leite: que belezaaaa hein? ... Não é do nada que a performance dos INSERTs está horrível ...

Bem, deixando de lado esta indignação com o problema, vem a pergunta: Como otimizar estas operações sobre estas tabelas?

A primeira, e mais sensata idéia, porém a longo prazo, é questionar desenvolvedores e usuários sobre qual a utilidade destes dados e a real necessidade de serem armazenados integralmente todo o mês. Ainda, não podemos estipular uma política de backup e mantermos apenas os dados do último ano, por exemplo? Essas são algumas medidas que podem ser implementadas e que ajudarão a resolver o problema sem recorrer as features do Oracle para eliminar o problema de performance.

Caso os usuários demorem um pouco a responder, a solução mais rápida é partir para recursos do ORACLE que possam melhorar a performance.

Vamos a elas então ...

A primeira análise que fiz, foi verificar a configuração do parâmetro DB_FILE_MULTIBLOCK_READ_COUNT cuja influência no otimizador e nos tempos para executar FULL TABLE SCAN é muito grande. Este parâmetro, no meu caso, estava com configuração de valor 8 e imediatamente o modifiquei para 32. Vale lembrar que este parâmetro é dinâmico, então sua configuração já passa a ser utilizada para novas sessões no BD.

Feito isso, fui atrás de features que poderiam melhorar a performance dos INSERTS. Recorri, no manual Design And Tuning for Performance, à hint PARALLEL do Oracle. Seu uso paraleliza a operação de INSERT utilizando o número de server process desejado para execução do comando. No meu caso, utilizei o grau de paralelismo 8 coincidindo com o número de núcleos de processamento do servidor de banco de dados.

Exemplo do comando: 

INSERT /*+ PARALLEL(my_target_table, 8) */ into my_target_table
(select * from my_source_table);

Para a minha surpresa o comando que, antes levava 6h para concluir, passou a ser executado em 15min. Isso mesmo, 15min !!!!
Isso demonstra o poder e versatilidade das features do Oracle. A simples adição de uma HINT no comando pode trazer resultados fantásticos de performance !!!

Até a próxima.

sábado, 15 de maio de 2010

DBLinks

Olá!

Vou falar de um tema que, na maioria das vezes, causa muita confusão para usuários e desenvolvedores, mas que na verdade não se trata de um "bicho de sete cabeças": DBLINKS. Depois de um certo tempo trabalhando com esses objetos, você acaba descobrindo que não são componentes tão complicados assim e que, na verdade, podem ser ótimos para controlar o acesso a objetos de uma outra instância.

Para familiarizar-se com o tema, primeiramente vamos entender o conceito e alguns dos tipos de  DBLinks existentes: um Database Link é um objeto do esquema em um banco de dados que possibilita você acessar objetos em um outro banco de dados. Detalhe importante: o banco de dados destino não precisa ser um RDBMS Oracle.

Consistem de 2 tipos:

PÚBLICO - Todos os usuários do BD conseguem ter acesso ao DBLink;
PRIVADO - Somente o OWNER do DBLink consegue acessá-lo.

Exemplo de como criar um Database Link:

Público

CREATE PUBLIC DATABASE LINK 'MeuDBLNK'
CONNECT TO 'user1' IDENTIFIED BY 'senha'
USING 'MeuBD'

Este DBLINK terá o nome 'MeuDBLNK', conectará no usuário 'user' cuja senha é 'senha' do banco de dados 'MeuBD'. Este objeto poderá ser acessado por todos os usuários do banco de dados.


Privado

CREATE DATABASE LINK 'MeuDBLNK'
CONNECT TO 'user1' IDENTIFIED BY 'senha'
USING 'MeuBD'

Para criar um DBLINK privado, apenas removemos a palavra-chave PUBLIC e esse DBLINK estará acessível apenas pelo o usuário OWNER do objeto.

Ok, mas como podem ser ótimos controladores de acesso conforme eu havia informado no primeiro parágrafo do texto?

Percebam que o DBLINK, tanto o público quanto o privado, conectam na instância 'MeuBD' através do usuário 'USER1'. Desta forma, quem utilizá-los só poderá acessar objetos na instância MeuBD que USER1 consegue acessar. Parece óbvio certo? Mas já cansei de ver DBLINKS PÚBLICOS conectando em instâncias diretamente no usuário/esquema OWNER de todos os objetos de uma aplicação, ou seja, deixando a aplicação inteira escancarada para todos os usuários que conseguem acessar o DBLINK.

Baseado nisso, recomendo a todos que criem na instância destino um usuário exclusivo para conectar DBLINKS e atribuam somente os privilégios necessários, e nada mais do que isso.

Existem mais tipos de DBLINKS que não citei no texto. Portanto, vale a pena uma consulta ao manual SQL da Oracle para conhecer todas as versatilidades de acesso desses objetos.

Até a próxima.