在以下示例中添加DISTINCT是否会对查询运行时间产生任何影响?
有时使用它作为暗示是明智的吗?
有时使用它作为暗示是明智的吗?
- SELECT *
- FROM A
- WHERE A.SomeColumn IN (SELECT DISTINCT B.SomeColumn FROM B)
解决方法
当想知道这样的事情时,你应该比较查询的执行计划.
查询的执行计划的形状当然会有所不同,具体取决于表中有多少行以及定义了哪些索引.
一个场景显示性能没有差异是A中的行数比B中的行多得多.优化器然后将选择B作为嵌套循环连接中的驱动表,以获得正确的结果.返回它必须在两个查询中使用表B上的Stream Aggregate来仅获取来自B的不同行.因此在这种情况下,distinct关键字对性能没有影响.
另外两个要测试的明显案例的执行计划,B中的行多于A和表中的行数相等,也显示了查询的完全相同的执行计划.
更新
在进行查询优化之前,查询将经历简化阶段.您可以使用跟踪标志8606查看逻辑树的外观.
查询的输入树明显不同,但在简化后它们是相同的.
参考:More Undocumented Query Optimizer Trace Flags和Query Optimizer Deep Dive – Part 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
- *******************
用于查询的输入树和简化树不使用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_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
- *******************