Banco de Dados

15 mai, 2013

Visões diferentes, mesmo resultado – entregando resultados com melhor performance

Publicidade

Analista de sistemas por formação –  e DBA por paixão -, estava sendo cobrado por ainda não ter escrito nada referente à banco de dados neste espaço. Pois bem, então vamos lá!

Estive pensando em quanto tempo nós, profissionais, investimos em discussões sobre as formas diferentes de resolução de um problema. É sempre a mesma história: cada um explicando por qual motivo a sua solução é a melhor de todas e, em alguns casos, tentando explicar que a solução do outro é pior que sua. Quem nunca passou por isso que atire a primeira pedra, pois não é somente na área de banco de dados que isso acontece. Equipes de desenvolvimento buscam sempre a arquitetura “perfeita”, o “melhor” código…

Um exemplo clássico dessa discussão é a construção de consultas em SQL. Quando recebemos uma demanda, o que importa para o usuário, na maioria dos casos, é o resultado que ele vai receber na tela. O problema é que o mesmo resultado pode ser obtido de diversas maneiras. E é aí o que o DBA deve entrar em ação na busca da performance de sua consulta, atentando para aqueles milésimos de segundos que fazem muita diferença. Uma consulta mal desenvolvida pode acarretar em sérios problemas nas aplicações que a estiverem consumindo.

Para exemplificar, vamos observar o modelo representado abaixo:

Imagem1
Tabela [Funcionario]
Temos uma tabela [Funcionario], que armazena os registros dos funcionários da empresa; uma tabela [Setor], que armazena os setores da empresa e está relacionada com [Funcionario]; e uma tabela [horaExtra], que armazena os registros horas extras dos funcionários da empresa e também está relacionada com a tabela [Funcionario].

Logo em seguida, visualizamos as tabelas já com os dados:

Tabela [Setor]
Tabela [Setor]
Tabela [Funcionario]
Tabela [Funcionario]
Tabela [horaExtra]
Tabela [horaExtra]
Agora, imaginando a demanda: precisamos contabilizar as horas extras de cada funcionário no ano de 2013.  Após a execução de consulta, o resultado seria:

Resultado da consulta
Resultado da consulta

Perfeito, chegamos ao resultado. O cliente está satisfeito, mas qual consulta foi feita para chegarmos a este resultado? E que custo ela terá para o banco de dados toda vez que precisar ser executada?

Para o cliente que recebe o resultado, caso não esteja demorando muito, pouco importa a forma como foi feito, mas o profissional deve estar sempre atento a este “detalhe”, que é a performance.

Nos quadros abaixo, mostro quatro opções de consulta para obtermos o mesmo resultado:

Primeira opção:

select
	f.IDFuncionario, f.Nome, sum(he.qtdHoraExtra) 'qtdHoraExtra'
from
	funcionario f inner join horaExtra he on f.IDFuncionario = he.IDFuncionario 
where
	he.anoReferencia = 2013
group by
	f.IDFuncionario, f.Nome
go

Segunda opção:

select
	f.IDFuncionario, f.Nome, he.qtdHoraExtra
from
	funcionario f inner join 
	( 
		select 
			he.IDFuncionario, sum(he.qtdHoraExtra) 'qtdHoraExtra'
		from
			horaExtra he
		where
			he.anoReferencia = 2013
		group by
			he.IDFuncionario
	) he on f.IDFuncionario = he.IDFuncionario 
go

Terceira opção:

select
	f.IDFuncionario, f.Nome, 
	(
		select 
			sum(he.qtdHoraExtra) 
		from
			horaExtra he 
		where
			he.anoReferencia = 2013
			and he.IDFuncionario = f.IDFuncionario 
	) 'qtdHoraExtra'
from
	funcionario f
go

Quarta opção:

select
	f.IDFuncionario, f.Nome, sum(he.qtdHoraExtra) 'qtdHoraExtra'
from
	funcionario f, horaExtra he
where
	f.IDFuncionario = he.IDFuncionario 
	and he.anoReferencia = 2013
group by
	f.IDFuncionario, f.Nome
go

Eu, particularmente, ao longo dos anos já utilizei cada uma dessas formas de escrever consultas. A ideia aqui não é discutir a que é melhor e nem a pior, mas sim aquela que apresenta a melhor performance.

Defendo que cada um deve utilizar sempre aquilo que se adeque à sua realidade e ao seu ambiente, mas algumas questões quando podem ser medidas, como é o caso da performance, devem ser respeitadas.

Para testar estas consultas, fiz cinco execuções de cada uma delas capturando o tempo de execução. Repeti este ciclo mais duas vezes. Dos tempos capturados, removi o maior e o menor valor de cada consulta e fiz uma média de tempo. Na medição que realizei, a consulta que apresentou a melhor performance foi a primeira consulta, como mostra a tabela abaixo:

Consulta

Média Final

1

5,11

4

5,67

3

6,44

2

7,56

Tentei fazer testes rápidos e simples para provar o conceito com números e estimar durante quanto tempo deveria discutir com alguém a melhor solução para a consulta: 10 minutos. É isso.

O fato é que devemos parar de discutir o sexo dos anjos e nos atentar às coisas que realmente interessam. Como já falei isso serve para tudo. No mundo de hoje, não temos mais tempo para “assim fica mais bonitinho” ou “assim é mais legal” e blá, blá, blá.

Devemos ser objetivos e entregar aos clientes aquilo que realmente funciona, mesmo que de uma forma “diferente”.

Até a próxima!