Eu vi alguém trocando o código abaixo:
SELECT
PK1
, PK2
, PK3
, PK4
, C
, B
, SUM(NUMERIC_1)
, SUM(NUMERIC_2)
, MAX(NUMERIC_3)
, SUM(NUMERIC_4)
FROM MATDOC_EXTRACT
WHERE A = ''
AND (
(
(
B = ''
OR B = 'K'
)
AND (
C = '01'
OR C = '02'
OR C = '07'
OR C = '08'
)
)
OR (
B = ''
AND (
C = '03'
OR C = '04'
)
)
)
GROUP BY PK1
, PK2
, PK3
, PK4
, C
, B;
para este
SELECT
PK1
, PK2
, PK3
, PK4
, C
, B
, SUM(NUMERIC_1)
, SUM(NUMERIC_2)
, MAX(NUMERIC_3)
, SUM(NUMERIC_4)
FROM sap.MATDOC_EXTRACT
WHERE A = N''
AND B = N''
AND C IN (N'01', N'02', N'07', N'08', N'03', N'04')
GROUP BY PK1
, PK2
, PK3
, PK4
, C
, B
UNION ALL
SELECT
PK1
, PK2
, PK3
, PK4
, C
, B
, SUM(NUMERIC_1)
, SUM(NUMERIC_2)
, MAX(NUMERIC_3)
, SUM(NUMERIC_4)
FROM sap.MATDOC_EXTRACT
WHERE A = N''
AND B = N'K'
AND C IN (N'01', N'02', N'07', N'08')
GROUP BY PK1
, PK2
, PK3
, PK4
, C
, B;
eles são iguais?
Uma diferença potencialmente importante é que no segundo caso os literais são
nvarchar
e no primeiro caso sãovarchar
.Ignorando esse aspecto, no entanto...
Sim
Pode ser reescrito como
Desde que
predicate_a
epredicate_b
sejam mutuamente exclusivos.Caso contrário, as linhas que corresponderem a ambos
predicate_a
serãopredicate_b
retornadas incorretamente duas vezes.Neste caso, como os dois ramos do
UNION ALL
incluem e incluempredicate_a
, esta condição é atendida.B = N''
predicate_b
B = N'K'
No seu caso, você tem 10 predicados de igualdade diferentes
A, B, C
- portanto, se você tiver um índice com essas colunas em alguma ordem, potencialmente ele poderá ser resolvido por dez predicados de busca.Reescrever
OR
asUNION ALL
vezes pode ser uma técnica útil quando a consulta escritaOR
não fornece as buscas de índice desejadas ou tem outros aspectos indesejáveis.Se eu tentar
Então o plano de execução se parece com
O plano de execução essencialmente o divide em dois operadores de busca de índice separados e
UNION ALL
os dois juntosEntre os dois operadores de busca, os 10 intervalos completos de busca do índice são expandidos.
Por alguma razão, parece que eles não se sobrepõem e há uma etapa para remover duplicatas.
A
UNION ALL
reescrita evita isso neste caso