Temos um gerador SQL que emite instruções condicionais SQL genericamente para os campos especificados (que, para fins de discussão: rotularemos como myField
).
Se myField
é do tipo NVARCHAR
, nós podemos fazer uma comparação do referido campo contra uma string assim: myField = 'foo'
.
No entanto, isso não funciona para campos do tipo NTEXT
. Assim, nós temos que fazer a comparação com um elenco: CAST(myField as NVARCHAR(MAX)) = 'foo'
. De fato, isso funcionará se myField
for do tipo NVARCHAR
ou NTEXT
.
Qual é o impacto no desempenho de fazer o elenco mencionado 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 efetivamente o CAST
não-op).
fonte
Respostas:
Se o elenco da coluna tem exatamente o mesmo tipo de dados e comprimento e o predicado de busca é literal, ele parece desconsiderá-lo ou tratá-lo como não operacional e um índice procura a igualdade.
Se a conversão da coluna for do mesmo tipo de dados, mas com maior comprimento e o predicado de busca for uma string literal, isso causará uma varredura de índice. Obviamente, isso deve ser evitado.
Se a conversão da coluna tiver o mesmo tipo de dados e o mesmo comprimento ou maior 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.Esse intervalo é usado para fazer uma busca de índice e parece bastante eficiente
Código de teste
fonte
Em geral, o
CAST
desempenho prejudicará porque invalida qualquer uso de pesquisas de índice, como mostra o último exemplo de Martin Smith. Converter paranvarchar(max)
ou para um comprimento diferente significa um tipo de dados diferente: o fato é que tudo issonvarchar
é 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 estará implicitamente
CAST
no mais amplo dos 2 tipos de dados (consulte a precedência do tipo de dados ).Basicamente, se você tem um general
CAST
paranvarchar(max)
ele vai bollix 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
fonte
Apenas uma observação: transmitir como este onde Datecreated é datetime
Não interrompe a capacidade do SQL de usar índices, se existirem, 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 sabe que a operação de conversão não altera a ordem de classificação dos dois tipos de dados comparáveis.Aqui estão alguns testes que você pode executar e visualizar o plano real usando o Adventureworks2008R2
fonte