Conversão Implícita no SQL Server — Performance Tuning
Antes de introduzir o assunto, gostaria de destacar que todo o artigo foi motivado por um acontecimento real. Aproveite a leitura!
Introdução
Ao comparar valores com tipos de dados diferentes, o SQL Server faz automaticamente uma conversão implícita antes de realizar essa comparação. Por exemplo, imagine um SELECT que recebe um filtro do tipo NVARCHAR em uma coluna que é VARCHAR:
Nesse caso temos uma conversão implícita de NVARCHAR para VARCHAR que fará nosso SELECT funcionar, porém isso trás sérios riscos de performance e vamos discutir sobre eles.
Por que Evitar Conversões Implícitas
A conversão implícita além de forçar uma carga de trabalho a mais, ela também pode confundir o MSSQL na geração de um bom plano de execução, mesmo que você tenha um bom índice. A queda de performance pode passar despercebida em tabelas pequenas, mas quando trabalhamos com tabelas grandes, o gargalo fica nítido.
Para exemplificar a diferença quando há conversão implícita, iremos usar a seguinte estrutura:
Exemplo de Plano de Execução Com Conversão Implícita
Neste exemplo é possível notar através do plano de execução que há uma conversão implícita e que o plano gerado faz um Index Scan. Esse plano poderia ser melhor.
Exemplo de Plano de Execução Sem Conversão Implícita
Agora neste exemplo nota-se que o plano gerado ficou bom, usando um Index Seek, que fará nossa query ter uma boa performance.
Exemplo de Um Case Real
Esse case será narrado contando a história de um desenvolvedor apelidado por um nome fictício: João.
João precisava desenvolver uma feature em uma aplicação C# que fizesse delete em uma base de dados SQL Server, então escreveu a query e rodou no MSSQL Management Studio:
A performance estava ótima, executando em poucos milisegundos.
Então João foi para o próximo passo, implementou a query na aplicação usando Dapper:
Porém ao executar a aplicação, a query rodava por minutos e sempre tomava timeout. Então surge o questionamento:
Por que no C# a performance está ruim mas no Management Studio está boa?
Após dias procurando a resposta, João descobre que o problema se tratava de conversão implícita e o responsável por isso, era o Dapper, que convertia o parâmetro CodigoAtivo de String para NVARCHAR.
Para resolver isso, João precisou tipar explicitamente o tipo de dado enviado para o Dapper:
Depois disso, a query voltou a executar em milisegundos.
Conclusão
Ás vezes a conversão implícita pode passar despercebida. E esse artigo foi escrito especialmente para isso. Agora você poderá usar esse conhecimento para não passar horas procurando um problema tão minucioso como este.
Bônus
Conversão implícita não é algo estritamente ligado ao MSSQL, ela pode acontecer no Oracle também, por exemplo.
A conversão implícita não aparece em todos os casos e para saber quando ela pode acontecer, veja a tabela abaixo disponibilizada pela documentação da Microsoft: