Vamos examinar estas duas declaraçõ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 certa 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 Dividir por zero neste caso.
CONCLUSÃO:
Se C ++ / C # / VB está em curto-circuito, por que o SQL Server não pode ter?
Para realmente responder a isso, vamos dar uma olhada em como os dois trabalham com as condições. Todos os C ++ / C # / VB possuem curto-circuito definido nas especificações de linguagem para acelerar a execução do código. Por que se preocupar em avaliar as condições N OU quando o primeiro já é verdadeiro ou M e condições quando o primeiro já é falso.
Nós, como desenvolvedores, precisamos estar cientes de que o SQL Server funciona de maneira diferente. É um sistema baseado em custo. Para obter o plano de execução ideal para nossa consulta, o processador de consultas deve avaliar todas as condições where e atribuir um custo a ela. Esses custos são então avaliados como um todo para formar um limite que deve ser menor que o limite definido que o SQL Server possui para um bom plano. Se o custo for menor que o limite definido, o plano será usado; se não, todo o processo será repetido novamente com uma combinação diferente de custos de condição. O custo aqui é uma junção de varredura, busca ou mesclagem ou 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 curto-circuito, mas não. Isso força apenas o uso desse índice e, com isso, reduz 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 provoca curto-circuito, como é feito em outras linguagens de programação e não há nada que você possa fazer para forçá-lo.
Respostas:
Não há garantia no SQL Server se ou em que ordem as instruções serão processadas em uma
WHERE
cláusula. A expressão única que permite um curto-circuito na declaração éCASE
-WHEN
. O seguinte é de uma resposta que eu publiquei no Stackoverflow:Como o SQL Server provoca um curto-circuito na avaliação da condição
Para mais detalhes, verifique o primeiro link na entrada do blog acima, que leva a outro blog:
O SQL Server está em curto-circuito?
fonte
case
não é seguroCASE
breaks: dba.stackexchange.com/questions/12941/...No T-SQL, a
IF
instrução pode causar um curto-circuito, mas você não pode confiar nela para avaliar as expressões em ordemfonte
SQL é 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 )
WHERE
é usar visualizaçõ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 em mencioná-lo, enquanto estamos neste tópico ...
fonte
1) - OU (qualquer uma ou ambas as condições serão VERDADEIRAS)
se a condição 1 for VERDADEIRA, a condição 2 também será verificada, podendo ser VERDADEIRA ou FALSA
--AND (as duas condições devem ser VERDADEIRAS)
se a condição 1 for FALSE, a condição 2 não será verificada
fonte
WHERE
cláusulas.A única maneira de controlar como as condições da cláusula WHERE é usar colchetes para agrupá-los.
é muito diferente de
fonte
AND
tem precedência mais alta queOR
. Ambos são equivalentes. O que você diz seria verdadeiro para aWHERE Col1 = x AND (Col2 = x OR Col3 = x) AND Col4 = x
consulta. Veja teste SQL-Fiddle