Vamos examinar essas duas afirmações:
IF (CONDITION 1) OR (CONDITION 2)
...
IF (CONDITION 3) AND (CONDITION 4)
...
Se CONDITION 1
for TRUE
, será CONDITION 2
verificado?
Se CONDITION 3
for FALSE
, será CONDITION 4
verificado?
E as condições em WHERE
: o mecanismo do SQL Server otimiza todas as condições em uma WHERE
cláusula? Os programadores devem colocar as condições na ordem correta para garantir que o otimizador do SQL Server as resolva da maneira correta ?
ADICIONADO:
Obrigado a Jack pelo link, surpresa do código t-sql:
IF 1/0 = 1 OR 1 = 1
SELECT 'True' AS result
ELSE
SELECT 'False' AS result
IF 1/0 = 1 AND 1 = 0
SELECT 'True' AS result
ELSE
SELECT 'False' AS result
Não há uma exceção de divisão por zero neste caso.
CONCLUSÃO:
Se C++/C#/VB tem curto-circuito, por que o SQL Server não pode ter?
Para realmente responder a isso, vamos dar uma olhada em como ambos funcionam com condições. C++/C#/VB todos têm curto-circuito definido nas especificações da linguagem para acelerar a execução do código. Por que se preocupar em avaliar condições N OR quando a primeira já é verdadeira ou condições M AND quando a primeira já é falsa.
Nós, como desenvolvedores, temos que estar cientes de que o SQL Server funciona de maneira diferente. É um sistema baseado em custos. Para obter o plano de execução ideal para nossa consulta, o processador de consulta deve avaliar todas as condições e atribuir um custo. Esses custos são então avaliados como um todo para formar um limite que deve ser inferior ao limite definido que o SQL Server tem para um bom plano. Se o custo for inferior ao limite definido, o plano é usado, caso contrário, todo o processo é repetido novamente com uma combinação diferente de custos de condição. O custo aqui é uma varredura ou uma busca ou uma junção de mesclagem ou uma junção de hash etc... Por causa disso, o curto-circuito disponível em C++/C#/VB simplesmente não é possível. Você pode pensar que forçar o uso de índice em uma coluna conta como um curto-circuito, mas não é. Apenas força o uso desse índice e com isso encurta a lista de possíveis planos de execução. O sistema ainda é baseado em custos.
Como desenvolvedor, você deve estar ciente de que o SQL Server não faz curto-circuito como é feito em outras linguagens de programação e não há nada que você possa fazer para forçá-lo.
Não há garantia no SQL Server se ou em que ordem as instruções serão processadas em uma
WHERE
cláusula. A única expressão que permite o curto-circuito da instrução éCASE
-WHEN
. O seguinte é de uma resposta que postei no Stackoverflow:Como o SQL Server causa um curto-circuito na avaliação da condição WHERE
Para mais detalhes, verifique o primeiro link na entrada do blog acima, que está levando a outro blog:
O SQL Server faz curto-circuito?
No T-SQL, a
IF
instrução pode entrar em curto-circuito, mas você não pode confiar nela avaliando as expressões em ordemSQL é uma linguagem de programação declarativa . Ao contrário, digamos, C++, que é uma linguagem de programação imperativa .
Ou seja, você pode dizer o que deseja no resultado final, mas não pode ditar como o resultado está sendo executado, tudo depende do mecanismo.
A única maneira verdadeira de garantir "curto-circuito" (ou qualquer outro fluxo de controle ) dentro
WHERE
é usar exibições indexadas, tabelas temporárias e mecanismos semelhantes.PS. Você também pode usar dicas de plano de execução (para "sugerir" ao mecanismo como executar uma consulta, quais índices usar e COMO usá-los), apenas pensei que deveria mencioná-lo, enquanto estamos neste tópico ...
A única maneira de controlar como as condições dentro da cláusula WHERE é usar colchetes para agrupá-las.
é muito diferente de
1)--OU (qualquer uma ou ambas as condições serão TRUE)
se a condição 1 for TRUE, a condição 2 também será verificada, pode ser TRUE ou FALSE
--AND (ambas as condições devem ser TRUE)
se a condição 1 for FALSE então a condição 2 não será verificada