Foi-me sugerido que o uso de instruções IF em lotes t-SQL é prejudicial ao desempenho. Estou tentando encontrar alguma confirmação ou validar esta afirmação. Estou usando o SQL Server 2005 e 2008.
A afirmação é que, com o seguinte lote:
IF @parameter = 0
BEGIN
SELECT ... something
END
ELSE
BEGIN
SELECT ... something else
END
O SQL Server não pode reutilizar o plano de execução gerado porque a próxima execução pode precisar de uma ramificação diferente. Isso implica que o SQL Server eliminará totalmente uma ramificação do plano de execução, pois, para a execução atual, ele já pode determinar qual ramificação é necessária. Isso é mesmo verdade?
Além disso, o que acontece neste caso: -
IF EXISTS (SELECT ....)
BEGIN
SELECT ... something
END
ELSE
BEGIN
SELECT ... something else
END
onde não é possível determinar antecipadamente qual ramificação será executada?
sql-server
sql-server-2008
sql-server-2005
query-performance
AnthonyWJones
fonte
fonte
Respostas:
O SQL Server otimiza o processo de compilação do plano de consulta para o procedimento armazenado ignorando as ramificações condicionais dentro do procedimento armazenado. O plano será gerado com base nos parâmetros usados para a primeira execução, isso causará problemas se os parâmetros forem diferentes para as ramificações.
Eu colocaria o SQL para cada uma das ramificações em seu próprio procedimento armazenado, para que o plano gerado se baseie no uso real dos parâmetros para essa ramificação.
fonte
O único atalho será
IF 1 = 1
@Parameter e EXISTS ainda requerem processamento para o "caso geral" (
@parameter = 42
digamos)Dizendo isso ... o que o plano de execução real diz, bem como o criador de perfil capturando eventos de recomposição? (Eu não gosto de planos estimados de acordo com a resposta de Jao)
fonte
Tente exibir o plano de execução estimado, não o real. Você verá que o primeiro contém o
COND
operador.Esse operador também foi incluído no plano de execução em cache. No seu exemplo, o plano de extração estimado conterá um operador COND e 2 filiais SELECT e, portanto, será totalmente reutilizável. Porque, ao executar um lote, o SQL Server avalia não apenas instruções DML, mas também todas as outras, obtendo-as do plano.
O plano de execução interna é uma estrutura semelhante à árvore de expressões.
fonte
Os planos serão criados com base nos parâmetros passados, portanto, na realidade, eu diria Não - ter uma lógica condicional que normalmente é baseada em parâmetros não prejudica o desempenho.
Você obterá vários planos produzidos, assumindo que os parâmetros causem uma variação suficiente para o otimizador de consultas perceber.
Você pode ver qual, ativando o plano Show Execution, executando os scripts - observe as diferenças no plano. Ao executar os procedimentos (estou assumindo procedimentos armazenados aqui), você notará que a primeira vez é geralmente mais rápida, a segunda ocorrência usa o plano armazenado. Altere os parâmetros e repita e execute os parâmetros originais - em teoria, o plano ainda estará no cache, mas depende do uso do servidor (marcações de cache - eles não ficam para sempre ...) etc.
fonte
Talvez tenha sido aprimorado em 2005 e 2008, mas o uso de condicionais em 2000 provavelmente seria pior do que o descrito, ele compilaria um plano para lidar melhor com a primeira execução do procedimento e, em seguida, usaria esse plano para executar o procedimento mesmo quando as condições mudou. Na minha experiência, isso causou consultas que eram executadas em minutos para serem executadas em horas. Embora eu use 2008 agora e usei 2005, não posso comentar sobre como os códigos funcionam lá, pois não os uso mais.
fonte