Yos*_*ari 19 sql-server-2008 sql-server
DISTINCT在下面的例子中添加对查询运行时间有什么影响吗?
有时将其用作提示是否明智?
SELECT *
FROM A
WHERE A.SomeColumn IN (SELECT DISTINCT B.SomeColumn FROM B)
Run Code Online (Sandbox Code Playgroud)
Mik*_*son 25
当想知道这样的事情时,您应该比较查询的执行计划。
查询的执行计划的形状当然会有所不同,具体取决于表中有多少行以及定义了哪些索引。
一种表明性能没有差异的场景是 in 中的行数A远多于 in 中的行数B。然后优化器将选择B作为嵌套循环连接中的驱动表A。为了获得正确的结果,它必须B在两个查询中都使用表上的流聚合来仅从B. 所以在这种情况下,distinct 关键字对性能没有影响。

要测试的另外两个明显案例的执行计划,B 中的行多于 A 并且表中的行数相等,也显示了完全相同的查询执行计划。
更新
在进行查询优化之前,查询会经历一个简化阶段。您可以使用跟踪标志 8606 查看逻辑树的样子。
查询的输入树明显不同,但经过简化后它们是相同的。
参考:更多未记录的查询优化器跟踪标志和查询优化器深入研究 - 第 2 部分
使用distinct进行查询的输入树和简化树:
*** 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
*******************
Run Code Online (Sandbox Code Playgroud)
不使用不同的查询的输入树和简化树:
*** 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
*******************
Run Code Online (Sandbox Code Playgroud)