Você está na página 1de 5

Ferramentas ORM e os Bancos de Dados Estruturados

Elaborado e escrito por Hemerson Ravaneda e Marlos Santos.

Em tempos de desenvolvimento rpido de aplicaes, metodologias, tcnicas e frmulas


mgicas para a produo de aplicaes, notvel o crescimento da criao e uso de
ferramentas de ORM (object relational mapping), isto , ferramentas para mapeamento
objeto-relacional. Estas ferramentas ORM tem por objetivo traduzir dados estruturados em
tabelas de bancos de dados em objetos de programao e, tambm, o caminho contrrio.
Quando utilizado de forma mais completa, as ferramentas de ORM podem ser utilizadas para a
criao das estruturas dos bancos de dados a partir dos objetos escritos pelos desenvolvedores
em projetos de software. Desta forma, tudo nasce a partir dos objetos e os desenvolvedores
de sistema no precisam ter conhecimento de como as informaes so persistidas ou
recuperadas nos bancos de dados.
Outra abordagem, que pode ser vista como hbrida, quando uma equipe desenha a soluo
atravs da anlise do negcio, documenta e gera um diagrama de entidades e seus
relacionamentos. Este diagrama costuma ser uma representao exata das tabelas criadas nos
bancos de dados. Os desenvolvedores precisam, a partir disto, configurar a ferramenta de
ORM para fazer uma comunicao com esta estrutura j pronta. Este texto trata desta
abordagem.
Muitas vezes (muitas mesmo), reclamaes so feitas aos responsveis do banco de dados na
seguinte tnica: Nossa, est muito lento. O banco de dados no est dando conta, ou
precisamos trocar o banco de dados j que esse no est entregando o resultado no tempo
esperado, ou pior ainda o banco est lento. Reclamaes estas partem de todos os
envolvidos no projeto como os prprios desenvolvedores, lideranas e at os usurios finais do
sistema; so descritos na sequncia alguns cenrios obtidos com esta abordagem.
Em um dos casos presenciados, uma empresa contava com um servidor biprocessado, sendo
cada processador com seis ncleos, e 96 GB de memria. Um determinado processo
gigantesco (processava aproximadamente 200 milhes de registros de uma tabela principal)
levava at 10 horas com consumo de 100% dos recursos da mquina. Ora, a concluso que
costuma parecer bvia neste caso aumentar a capacidade de processamento e a quantidade
de memria do servidor. Com mais espao para cach e mais capacidade de processamento, o

resultado pode ser obtido mais rapidamente. Neste enfoque, a empresa adquiriu um novo
servidor com quatro processadores, 10 ncleos por processador e 512 GB de memria. Era
esperado que esse novo servidor seria capaz de entregar a resposta num tempo considerado
hbil (menos de uma hora). Entretanto, o processo que levava at 10 horas, passou a levar, em
mdia, 12 horas. Acompanhando o processo minuciosamente, o processamento no era mais
problema, pois apresentava picos de apenas 12% de consumo. A memria reservada estava
suficiente e o banco de dados no apresentava waits, locks, limitaes de recursos, nada.
Consequentemente, as reclamaes citadas acima surgiram e tambm concluses empricas
como o SQLServer (banco de dados utilizando nesse caso) no aguenta uma base desse
tamanho. Testes foram feitos com o Oracle e os resultados foram similares. Onde estaria o
problema? Se o processo era o mesmo, porque no conseguia utilizar todo o potencial do
processador? Foi iniciada uma anlise mais profunda do processo e cogitado que o problema
poderia estar na forma como a aplicao solicitava essas informaes ao banco de dados.
Poderia ser interessante implementar o processo no prprio banco de dados. A proposta soou
praticamente ofensiva equipe desenvolvimento, j que todas as best practices haviam sido
implementadas. A ttulo de informao, o banco de dados ficava armazenado em um storage
com 48 discos em RAID 5, com discos de 15k RPM. Ou seja, no era gargalo de IO.
Em uma outra empresa ocorria um problema infinitamente menor, mas tambm preocupante.
Quando um determinado produto entrou em operao foi feita a converso de dados de um
sistema antigo, aumentando bruscamente o nmero de registros armazenados nas tabelas do
banco de dados e a emisso de um relatrio especfico (que deveria ocorrer em at 15
segundos) passou a gastar absurdos 27 minutos. Mas neste caso o processamento e memria
no eram problema para o banco de dados, j que o processo consumia 6% de processamento
e a memria de 4 GB era mais que suficiente para a operao. Para uma anlise mais
detalhada, foi utilizado um profiler, buscando todas as consultas que consumiam mais de 3
segundos na execuo. Nada foi retornado para esta condio. Analisando a aplicao,
tambm no foi detectado problemas com recursos. Aps muita procura e monitorando as
requisies da aplicao ao banco de dados foi detectado o problema: o nmero de
requisies por segundo. Ambos os casos citados utilizavam uma ferramenta ORM.
O problema detectado, na realidade, muito conhecido. Entretanto, em tempo de
desenvolvimento muito difcil averiguar problemas em relao ao desempenho devido essa
ocorrncia. O nome tcnico do mesmo N+1 Queries. As classes escritas na aplicao
mapeiam suas propriedades para suas respectivas estruturas no banco de dados utilizando a
ferramenta de ORM. Entretanto, um objeto pode conter uma coleo de objetos de outro tipo

dentro dele. Esta a forma de relacionar dados em objetos que equivalente uma tabela
ligada outra em um banco de dados. Este outro tipo, por sua vez, pode conter outras
colees de outros tipos dentro dele e assim sucessivamente. A ttulo de exemplo, uma classe
nota fiscal, possui um campo chamado itens que uma coleo de objetos da classe item
de nota fiscal que, por sua vez, contm um produto. No banco de dados a representao
destas classes sero trs tabelas: nota fiscal, item e produto. Uma consulta utilizando joins
consegue trazer os dados j relacionados para cada nota fiscal. Entretanto, uma ferramenta
ORM pode ser configurada para utilizar um conceito chamado carregamento tardio. Este
carregamento far uma consulta para cada dado de uma classe aninhada apenas quando for
necessrio. Isto faz com que j sejam disparados contra o banco de dados uma quantidade
expressiva de consultas. O problema N+1 est relacionado especificamente no caso em que
uma consulta utiliza uma clusula de filtragem que envolve trazer uma entidade pai com
alguma restrio na coleo dos filhos, por exemplo: localizar pessoas que tenham um
endereo em uma cidade especfica. Em SQL, seria:
select p.* from pessoa p inner join endereco e
on p.Id = e.IdPessoa where e.cidade = londrina;

J utilizando ORM com carregamento tardio, sero enviados separadamente os seguintes


comandos ao banco de dados:
select * from pessoa;
Aps isso o sistema percorre pelas pessoas encontradas e envia um comando para cada pessoa
na base de dados como este:
select * from endereco where idpessoa = @idPessoa and cidade = londrina;
Da o nome do problema, uma query para buscar a entidade pai e N queries, ou seja, quantos
pais houverem, na entidade filho. Caso no seja utilizado o carregamento tardio, a ferramenta
de ORM pode gerar consultas utilizando joins, no entanto, caso haja as tabelas sejam
interligadas em teias ou em uma sequncia de relacionamentos muito longa, a consulta para
materializar os objetos pode vir a carregar uma quantidade inconcebvel de dados em uma
nica consulta. claro que erros de design do modelo podem agravar este cenrio.
Vale salientar que um agravante em relao a este problema tem justamente a ver com as
boas prticas de desenvolvimento, como por exemplo o baixo acoplamento de classes. Em um
projeto de maior proporo, no se pode (por questes de boas prticas) acoplar um

framework ORM regra de negcio, pois, se o framework for descontinuado, ele ter que ser
facilmente substituvel. Com alto acoplamento isto se torna uma tarefa complexa. Em geral,
por isso, as ferramentas de ORM so posicionadas em um projeto para serem o mais
transparente possvel. Em consequncia, os desenvolvedores no se preocupam com nenhum
aspecto do comportamento do framework e, mesmo tendo a preocupao, no possuem
meios de configurar a ferramenta em tempo de execuo por estarem desacoplados do
framework. O que ocorre nestes casos uma configurao de alto nvel (global) que, no caso
do carregamento tardio configurado uma nica vez para todo o ciclo de execuo. Esta
configurao pode funcionar para projetos de pequeno porte, mas quando o nmero de
registros comea a crescer, algum contorno deve ser feito para otimizar os casos mais
complexos. Em geral, esse contorno se torna o uso de procedimentos armazenados no prprio
banco de dados, que causa gera um acoplamento altssimo com o sistema gerenciador de
banco de dados.
Voltando aos casos estudados, porque, no primeiro caso, um servidor menor era capaz de
entregar o resultado mais rapidamente que o servidor maior? Com o mecanismo de
carregamento tardio da ferramenta de ORM ativo, um gigantesco nmero de requisies era
disparado contra o servidor. O servidor antigo possua processadores com clock de 3 GHz, e o
servidor novo, apesar de possuir muito mais ncleos de processamento, trabalhava em um
clock de 1,9 GHz. Como cada requisio continha, em si, uma consulta extremamente simples,
o banco de dados no conseguia dividir a tarefa recebida em tarefas menores e utilizar, assim,
outros ncleos do processador. Enfim, o processo se tornava um enfileiramento indivisvel e,
neste caso, processadores com clock mais alto conseguem responder em menor tempo um
mesmo nmero de requisies.
Os dois casos estudados continham o mesmo problema: a forma da utilizao da ferramenta
ORM. Com a alterao da aplicao para utilizar o carregamento imediato em alguns casos e a
migrao de processos mais onerosos para procedimentos armazenados no banco de dados,
os gargalos foram suprimidos. Em alguns casos foram feitas alteraes no design do modelo do
banco de dados afim de facilitar a gerao de consultas pela ferramenta de ORM e
consequentemente aumentar o desempenho global da aplicao. Torna-se possvel concluir
que, a separao completamente desacoplada de regras de negcio, camada de persistncia
(utilizando ORM) e banco de dados deve ser minuciosamente mensurada. H sempre um custo
envolvido que dever ser pago em alguma camada do sistema. Boas prticas de
desenvolvimento em geral so inversamente proporcionais ao desempenho da aplicao
resultante (em relao ao armazenamento de dados, obviamente). Ao utilizar ferramentas

ORM em modelos relacionais construdos previamente, os desenvolvedores devem analisar o


volume de requisies enviado ao banco de dados e se precaver de possveis problemas de
desempenho com o crescimento da base de dados de uma aplicao.