Conversão Implícita – Vilão Silencioso

Fala Galera,
Espero que estejam todos bem!
Recentemente estava analisando uma query que estava rodando lenta em um cliente e descobri que o problema era justamente isso. Vou compartilhar com vocês o que aprendi sobre esse assunto.
Um caso real que me aconteceu
Depois de investigar, descobri que alguém havia alterado um parâmetro de entrada da procedure de VARCHAR para NVARCHAR (Não me pergunte o porque, estou até hoje tentando entender porque fizeram isso 🙃). Apesar de parecer uma mudança inocente, causou um estrago enorme na performance da procedure do cliente.
O que são essas conversões de Tipo?
Vamos entender melhor o que acontece por baixo dos panos.
Por exemplo, se você tentar somar o número 5 com a string ‘3’, o SQL Server vai converter a string ‘3’ para o número 3 e o resultado será 8.

Quando o SQL Server faz essas conversões sozinho?
Aqui está o ponto importante. Quando você não especifica explicitamente como quer que essa conversão seja feita, o SQL Server faz isso automaticamente para você. Isso é chamado de conversão implícita.
Na maioria das vezes isso funciona bem e nos ajuda a escrever código mais simples. Mas em alguns casos pode causar problemas sérios de performance.
Um exemplo prático para entendermos melhor
Vou mostrar um exemplo usando uma tabela de funcionários. Imaginem que temos uma coluna CodigoFuncionario definida como VARCHAR(10).
Primeiro cenário – sem conversão implícita:
1 2 3 4 5 6 |
DECLARE @codigo VARCHAR(10) = 'F001' SELECT Nome, Cargo, Salario FROM Funcionarios WHERE CodigoFuncionario = @codigo |
Neste caso, tanto a variável quanto a coluna são VARCHAR(10). O SQL Server consegue usar o índice normalmente e faz um Index Seek eficiente.
1 2 3 4 5 6 |
DECLARE @codigo NVARCHAR(10) = 'F001' SELECT Nome, Cargo, Salario FROM Funcionarios WHERE CodigoFuncionario = @codigo |
Agora mudei a variável para NVARCHAR(10). Aparentemente uma mudança pequena, mas que causa um impacto gigantesco.
O que acontece nos bastidores?
No nosso exemplo, o NVARCHAR tem precedência maior que o VARCHAR. Então o SQL Server vai converter a coluna CodigoFuncionario de VARCHAR para NVARCHAR antes de fazer a comparação.
É como se a query se tornasse isso:
1 2 3 4 5 6 |
DECLARE @codigo NVARCHAR(10) = 'F001' SELECT Nome, Cargo, Salario FROM Funcionarios WHERE CONVERT(NVARCHAR(10), CodigoFuncionario) = @codigo |
O Problema de performance
Aqui está o grande problema. Quando você aplica uma função (incluindo CONVERT) em uma coluna no WHERE, o SQL Server não consegue mais usar o índice de forma eficiente.
Ao invés de ir direto na linha que precisa (Index Seek), ele precisa ler toda a tabela ou todo o índice (Index Scan) aplicando a conversão em cada linha para depois fazer a comparação.
Em uma tabela pequena isso pode passar despercebido. Mas em uma tabela com milhões de registros, isso vira um pesadelo.
Como Identificar essas conversões?
Essa mensagem é um sinal vermelho de que você tem um problema de conversão implícita.

Como resolver o problema?
Opção 1 – Mudar o tipo da variável:
1 |
DECLARE @codigo VARCHAR(10) = 'F001' -- Volta para VARCHAR |
Opção 2 – Mudar o tipo da coluna:
1 2 |
ALTER TABLE Funcionarios ALTER COLUMN CodigoFuncionario NVARCHAR(10) -- Muda para NVARCHAR |
Opção 3 – Fazer a conversão explícita na variável:
1 2 3 4 5 6 |
DECLARE @codigo NVARCHAR(10) = 'F001' SELECT Nome, Cargo, Salario FROM Funcionarios WHERE CodigoFuncionario = CONVERT(VARCHAR(10), @codigo) |
A terceira opção força a conversão da variável ao invés da coluna, mantendo o índice utilizável.
Dicas Importantes para o dia a dia
- Sempre declare suas variáveis com o mesmo tipo das colunas que você vai comparar;
- Tenha cuidado especial com VARCHAR VS NVARCHAR – essa é uma pegadinha muito comum (Principalmente em ORMs : Entity Framework, Hibernate .. etc, as vezes é só questão de parametrizar corretamente na aplicação para evitar cair nessas armadilhas);
- Fique atento aos tipos de dados quando usar parâmetros em procedures e functions;
- Sempre analise os planos de execução procurando por avisos de conversão implícita;
- Se você precisar fazer conversões, prefira converter a variável/parâmetro ao invés da coluna;
Conclusão
Sempre que estiverem analisando problemas de performance, não se esqueçam de verificar se existem conversões implícitas acontecendo. Muitas vezes esse é o culpado pela lentidão.
É isso pessoal! Espero que essa dica possa ajudar vocês a evitarem dores de cabeça com performance no SQL Server.
Se já passaram por situações similares ou têm outras dicas sobre performance, compartilhem nos comentários! A troca de experiências sempre nos ajuda a crescer.
Gustavo Larocca