A adição DISTINCT
no exemplo a seguir tem algum impacto no tempo de execução da consulta?
É aconselhável usá-lo como uma dica às vezes?
SELECT *
FROM A
WHERE A.SomeColumn IN (SELECT DISTINCT B.SomeColumn FROM B)
A adição DISTINCT
no exemplo a seguir tem algum impacto no tempo de execução da consulta?
É aconselhável usá-lo como uma dica às vezes?
SELECT *
FROM A
WHERE A.SomeColumn IN (SELECT DISTINCT B.SomeColumn FROM B)
Respostas:
Ao se perguntar sobre coisas como essa, você deve comparar os planos de execução para suas consultas.
É claro que a forma do plano de execução da sua consulta varia dependendo de quantas linhas você tem em suas tabelas e de quais índices são definidos.
Um cenário que mostra que não há diferença no desempenho é quando há substancialmente mais linhas do A
que em B
. O otimizador escolherá B
como a tabela de controle em uma junção aninhada contra A
. Para obter um resultado correto, ele precisa usar um Stream Aggregate na tabela B
em ambas as consultas para obter apenas as linhas distintas B
. Portanto, nesse caso, a palavra-chave distinta não afeta o desempenho.
O plano de execução para dois outros casos óbvios para testar, mais linhas em B que A e número igual de linhas nas tabelas, também mostra exatamente o mesmo plano de execução para as consultas.
Atualizar
Antes da otimização da consulta, a consulta passa por uma fase de simplificação. Você pode ver como é a árvore lógica usando o sinalizador de rastreamento 8606.
A Árvore de Entrada para as consultas é claramente diferente, mas após a simplificação elas são as mesmas.
Ref: Mais sinalizadores de rastreamento do Query Optimizer não documentados e Deep Dive do Query Optimizer - Parte 2
Árvore de entrada e árvore simplificada para consulta usando distintas:
*** Input Tree: ***
LogOp_Project QCOL: [xx].[dbo].[A].SomeColumn
LogOp_Select
LogOp_Get TBL: A A TableID=213679909 TableReferenceID=0 IsRow: COL: IsBaseRow1002
ScaOp_SomeComp 2
ScaOp_Identifier QCOL: [xx].[dbo].[A].SomeColumn
LogOp_GbAgg OUT(QCOL: [xx].[dbo].[B].SomeColumn,) BY(QCOL: [xx].[dbo].[B].SomeColumn,)
LogOp_Project
LogOp_Project
LogOp_Get TBL: B B TableID=229679966 TableReferenceID=0 IsRow: COL: IsBaseRow1006
AncOp_PrjList
AncOp_PrjList
AncOp_PrjList
AncOp_PrjList
*******************
*** Simplified Tree: ***
LogOp_LeftSemiJoin
LogOp_Get TBL: A A TableID=213679909 TableReferenceID=0 IsRow: COL: IsBaseRow1002
LogOp_Get TBL: B B TableID=229679966 TableReferenceID=0 IsRow: COL: IsBaseRow1006
ScaOp_Comp x_cmpEq
ScaOp_Identifier QCOL: [xx].[dbo].[A].SomeColumn
ScaOp_Identifier QCOL: [xx].[dbo].[B].SomeColumn
*******************
Árvore de entrada e árvore simplificada para consulta que não usa distintas:
*** Input Tree: ***
LogOp_Project QCOL: [xx].[dbo].[A].SomeColumn
LogOp_Select
LogOp_Get TBL: A A TableID=213679909 TableReferenceID=0 IsRow: COL: IsBaseRow1002
ScaOp_SomeComp 2
ScaOp_Identifier QCOL: [xx].[dbo].[A].SomeColumn
LogOp_Project
LogOp_Get TBL: B B TableID=229679966 TableReferenceID=0 IsRow: COL: IsBaseRow1006
AncOp_PrjList
AncOp_PrjList
*******************
*** Simplified Tree: ***
LogOp_LeftSemiJoin
LogOp_Get TBL: A A TableID=213679909 TableReferenceID=0 IsRow: COL: IsBaseRow1002
LogOp_Get TBL: B B TableID=229679966 TableReferenceID=0 IsRow: COL: IsBaseRow1006
ScaOp_Comp x_cmpEq
ScaOp_Identifier QCOL: [xx].[dbo].[A].SomeColumn
ScaOp_Identifier QCOL: [xx].[dbo].[B].SomeColumn
*******************