Temos um gerador SQL que emite instruções condicionais SQL genericamente para campos especificados (que, para fins de discussão: rotularemos como myField
).
Se myField
for do tipo NVARCHAR
, podemos fazer uma comparação do referido campo com uma string da seguinte forma: myField = 'foo'
.
No entanto, isso não funciona para campos do tipo NTEXT
. Assim, temos que fazer a comparação com um elenco: CAST(myField as NVARCHAR(MAX)) = 'foo'
. Isso funcionará de fato se myField
for do tipo NVARCHAR
ou NTEXT
.
Qual é o impacto no desempenho de fazer a conversão mencionada em um campo que já é do tipo NVARCHAR
? Minha esperança é que o SQL Server seja inteligente o suficiente para reconhecer dinamicamente que myField
já é do tipo NVARCHAR
(transformando-o efetivamente CAST
em um no-op).
Se a conversão da coluna for exatamente do mesmo tipo de dados e comprimento e o predicado de busca for literal, ele realmente parece desconsiderá-lo ou tratá-lo como não operacional e um índice busca por igualdade.
Se a conversão da coluna for do mesmo tipo de dados, mas de comprimento maior, e o predicado de busca for uma cadeia de caracteres literal, isso causará uma varredura de índice. Isso obviamente deve ser evitado.
Se a conversão da coluna for para o mesmo tipo de dados e o mesmo ou maior comprimento e o predicado de busca for uma variável local, ele adicionará um operador escalar de computação ao plano de execução. Isso chama
GetRangeThroughConvert
e gera um intervalo.Este intervalo é usado para fazer uma busca de índice e parece bastante eficiente
Código de teste
Em geral, o
CAST
irá matar o desempenho porque invalida qualquer uso de busca de índice, como mostra o último exemplo de Martin Smith. A conversão paranvarchar(max)
ou para um comprimento diferente significa um tipo de dados diferente: o fato de ser tudonvarchar
é irrelevante.Além disso, o tipo de dados do lado direito da comparação também é importante. Se for uma variável local ou parâmetro de comprimento diferente, um lado será implicitamente
CAST
o mais amplo dos 2 tipos de dados (consulte precedência de tipo de dados ).Basicamente, se você tiver um general
CAST
,nvarchar(max)
isso estragará as coisas. Eu consideraria corrigir o uso dentext
antes de adicionarCAST
tudo.A conversão pode não aparecer no plano de consulta. Veja o artigo do blog de Paul White
Apenas uma observação, transmitindo assim, onde Datecreated é datetime
Não interrompe a capacidade do SQL de usar índices se existirem índices e, se não existirem, pode resultar no registro de um índice ausente.
Da mesma forma, ao converter de
int
paratinyint
oubigint
paraint
etc, a função de conversão não impede o SQL de usar índices SE o otimizador souber que a operação de conversão não altera a ordem de classificação dos 2 tipos de dados comparáveis.Aqui estão vários testes que você pode executar e visualizar o plano real usando o Adventureworks2008R2