Clique no banner para conhecer e adquirir o meu treinamento de Bancos de Dados no Azure

SQL Server – O perigo de utilizar JOIN entre colunas de tipos de dados diferentes

Visualizações: 731 views
Tempo de Leitura: 3 minutos

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:

SQL Server - JOIN Predicate Columns Different DataTypes 2

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.

SQL Server - JOIN Predicate Columns Different DataTypes 3

Raparem que hĂ¡ um warning no select. E ao posicionar o mouse sobre ele, podemos visualizar essas informações:
SQL Server - Differente Datatypes Performance Problems 2

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:

SQL Server - JOIN Predicate Columns Different DataTypes 1

SQL Server - JOIN Predicate Columns Different DataTypes 4

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!