Sou muito novo em qualquer tipo de ajuste, mas tenho aprendido mais. Um dos meus bancos de dados específicos, um dos problemas identificados com consultas lentas, são várias conversões implícitas. É meu entendimento que quando 2 tipos de coluna diferentes são comparados, o SQL Server precisa converter um para o outro, há uma lista de prioridades que informam como converter - Como o tipo de dados é convertido, é possível que ele não use índices corretamente.. Uma das primeiras consultas identificadas é bem básica, e gostaria de ver se alguém poderia me ajudar a identificar o que estou vendo no meu plano de execução...
A consulta básica é:
(
@1 TINYINT
,@2 VARCHAR(8000)
,@3 NUMERIC(4, 0)
)
SELECT CONVERT([float], [low] / @3, 0)
FROM [master].[dbo].[spt_values]
WHERE [number] = @1
AND [type] = @2
O plano de execução mostra:
Detalhes sobre a busca de índice clusterizado
spt_vaules.Type é definido como nchar(3)
A seção Seek Predicates está me confundindo, exatamente qual parte disso está convertendo ... Minha consulta diz que [low] está sendo convertido de int para numérico, mas isso não parece ser o que os detalhes de busca do índice de cluster estão mostrando, é isto?
Existe uma maneira de dizer neste exemplo específico quanto "melhor" seria se eu fizesse as conversões explicitamente? Eu acho que poderia apenas fazer um "cast" na consulta e inserir alguns números onde estão as variáveis, correto?
Por que seus parâmetros de entrada não correspondem ao tipo da tabela? Por que você deseja manter os tipos errados lá e executar qualquer conversão ou conversão (implícita ou explícita)? Por que você está convertendo qualquer coisa para
FLOAT
, de todas as coisas? Para responder a perguntas específicas:A conversão de
low
está acontecendo na saída, não no predicado de busca (o predicado é o que é usado para localizar linhas correspondentes e/ou eliminar linhas não correspondentes).Não há como fazer o plano de execução mostrar o quanto um plano diferente seria melhor, exceto gerar esse plano diferente e comparar. Você pode usar essa comparação para documentar o quanto seria melhor se a interface estivesse correta (e duas outras maneiras seriam manter a interface, mas (a) executar conversões explícitas na consulta - não da coluna, mas das variáveis ou (b) usar variáveis locais do tipo certo e atribuir a elas os valores dos parâmetros). Assim, você pode mostrar a eles 3 maneiras diferentes de resolver o problema e mostrar evidências de que todas as 3 são melhores que a versão atual.
Minha recomendação é corrigir o procedimento da maneira certa. Primeiro, vamos ver os tipos reais com os quais você se importa:
Resultados:
Portanto, a interface para o procedimento armazenado deve ser:
Conversões implícitas entre varchar e nvarchar podem ser particularmente ruins ( especialmente no cenário oposto ao seu - o parâmetro é nvarchar e a coluna é varchar ), mas realmente não há razão para permitir um parâmetro de 8.000 caracteres de qualquer tipo quando a string mais longa possível na tabela são 3 caracteres...