OlĂ¡ pessoal!
Boa noite!
Hoje me deparei com um problema crĂtico de performance em um ambiente de produĂ§Ă£o, onde uma determinada query (que pode ser executada vĂ¡rias vezes por segundo) estava apresentando um problema de lentidĂ£o (demorava entre 21 e 30 segundos por execuĂ§Ă£o) jĂ¡ antigo e conhecido, mas que hoje foi o dia de resolver isso de uma vez por todas.
Para muitos DBA’s (inclusive para mim) e entusiastas de modelagem de banco de dados, esse tipo de problema nĂ£o deveria ocorrer nunca, mas infelizmente na prĂ¡tica nĂ£o Ă© o que acontece. Analisando a query, que por sinal era bem grande, com vĂ¡rios CASES, LEFT JOIN’S, OR’s, uso de funĂ§Ă£o, etc pude observar que haviam muitos casos de conversĂ£o implĂcita e ao analisar o plano real de execuĂ§Ă£o, foi bem claro o motivo da lentidĂ£o:
Analisando as leituras em disco, podemos observar que as leituras em uma tabela especĂfica estĂ£o bem altas, principalmente se levarmos em conta que a query utiliza na clĂ¡usula WHERE um termo de igualdade na tabela principal da consulta, informando um cĂ³digo que Ă© chave primĂ¡ria e estĂ¡ no Ăndice clustered, ou seja, deveria ser uma consulta extremamente rĂ¡pida e otimizada, processando poucos registros.
Raparem que hĂ¡ um warning no select. E ao posicionar o mouse sobre ele, podemos visualizar essas informações:
Bom, temos o problema de conversĂ£o implĂcita ocorrendo. Isso ocorre quando duas colunas de tipos de dados diferentes sĂ£o comparadas e aĂ o banco precisa converter isso manualmente durante a consulta.
Analisando os JOINS da consulta, pude observar que as colunas envolvidas na comparaĂ§Ă£o eram de tipos diferentes. Isso faz com que todos os registros envolvidos no JOIN tenham que ser convertidos para o mesmo tipo, para depois verificar se eles devem ser restringidos pelas clĂ¡usulas no JOIN ou nĂ£o. Se o volume de registros for muito alto, isso pode aumentar consideravelmente o tempo de processamento e leituras em disco (como demonstrado no exemplo)
Um simples comando de ALTER TABLE na coluna que estava realizando o JOIN da tabela que estava com muitas leituras para igualar os tipos de dados resolveu o problema:
Uma outra soluĂ§Ă£o seria criar uma tabela intermediĂ¡ria contendo uma parte da query, e convertendo a coluna jĂ¡ para o tipo correto. Com essa tabela intermediĂ¡ria Ă© que seria realizado o JOIN com o restante da query, e agora, com o mesmo tipo de dado, nĂ£o havia mais o problema de conversĂ£o implĂcita e a query estaria sendo executada de forma mais otimizada.
É isso aĂ, pessoal!
Um abraço e atĂ© o prĂ³ximo post!
Ótimo artigo! Obrigada!
Ei!
Que bom que vocĂª gostou e espero ter ajudado