Uma visão inicial dos planos de execução mostra que a expressão 1/0
é definida nos operadores Compute Scalar:
Agora, apesar de os planos de execução começarem a ser executados na extrema esquerda, chamando iterativamente Open
e GetRow
métodos nos iteradores filhos para retornar resultados, o SQL Server 2005 e posteriores contêm uma otimização na qual as expressões geralmente são definidas apenas por um Escalar de computação, com a avaliação adiada para uma subseqüente operação requer o resultado :
Nesse caso, o resultado da expressão é necessário apenas ao montar a linha para retornar ao cliente (que você pode pensar em ocorrer no SELECT
ícone verde ). Por essa lógica, a avaliação adiada significaria que a expressão nunca é avaliada porque nenhum plano gera uma linha de retorno. Para esclarecer um pouco o ponto, nem a Pesquisa de índice em cluster nem a Verificação de tabela retornam uma linha; portanto, não há linha a ser montada para retorno ao cliente.
No entanto, existe uma otimização separada, na qual algumas expressões podem ser identificadas como constantes de tempo de execução e avaliadas uma vez antes do início da execução da consulta . Nesse caso, uma indicação disso ocorreu pode ser encontrada no showplan XML (plano de busca de índice em cluster à esquerda, plano de varredura de tabela à direita):
Escrevi mais sobre os mecanismos subjacentes e como eles podem afetar o desempenho nesta postagem do blog . Usando as informações fornecidas lá, podemos modificar a primeira consulta para que ambas as expressões sejam avaliadas e armazenadas em cache antes do início da execução:
select 1/0 * CONVERT(integer, @@DBTS)
from #temp
where id = 1
select 1/0
from #temp2
where id = 1
Agora, o primeiro plano também contém uma referência de expressão constante e as duas consultas produzem a mensagem de erro. O XML para a primeira consulta contém:
Mais informações: Escalares de computação, expressões e desempenho