sql-server – 使用DISTINCT作为子查询中的提示有用吗?

前端之家收集整理的这篇文章主要介绍了sql-server – 使用DISTINCT作为子查询中的提示有用吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
在以下示例中添加DISTINCT是否会对查询运行时间产生任何影响?
有时使用它作为暗示是明智的吗?
  1. SELECT *
  2. FROM A
  3. 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 FlagsQuery Optimizer Deep Dive – Part 2

使用distinct的输入树和简化树进行查询

  1. *** Input Tree: ***
  2. logop_Project QCOL: [xx].[dbo].[A].SomeColumn
  3. logop_Select
  4. logop_Get TBL: A A TableID=213679909 TableReferenceID=0 IsRow: COL: IsBaseRow1002
  5. ScaOp_SomeComp 2
  6. ScaOp_Identifier QCOL: [xx].[dbo].[A].SomeColumn
  7. logop_GbAgg OUT(QCOL: [xx].[dbo].[B].SomeColumn,) BY(QCOL: [xx].[dbo].[B].SomeColumn,)
  8. logop_Project
  9. logop_Project
  10. logop_Get TBL: B B TableID=229679966 TableReferenceID=0 IsRow: COL: IsBaseRow1006
  11. AncOp_PrjList
  12. AncOp_PrjList
  13. AncOp_PrjList
  14. AncOp_PrjList
  15. *******************
  16. *** Simplified Tree: ***
  17. logop_LeftSemiJoin
  18. logop_Get TBL: A A TableID=213679909 TableReferenceID=0 IsRow: COL: IsBaseRow1002
  19. logop_Get TBL: B B TableID=229679966 TableReferenceID=0 IsRow: COL: IsBaseRow1006
  20. ScaOp_Comp x_cmpEq
  21. ScaOp_Identifier QCOL: [xx].[dbo].[A].SomeColumn
  22. ScaOp_Identifier QCOL: [xx].[dbo].[B].SomeColumn
  23. *******************

用于查询的输入树和简化树不使用distinct:

  1. *** Input Tree: ***
  2. logop_Project QCOL: [xx].[dbo].[A].SomeColumn
  3. logop_Select
  4. logop_Get TBL: A A TableID=213679909 TableReferenceID=0 IsRow: COL: IsBaseRow1002
  5. ScaOp_SomeComp 2
  6. ScaOp_Identifier QCOL: [xx].[dbo].[A].SomeColumn
  7. logop_Project
  8. logop_Get TBL: B B TableID=229679966 TableReferenceID=0 IsRow: COL: IsBaseRow1006
  9. AncOp_PrjList
  10. AncOp_PrjList
  11. *******************
  12. *** Simplified Tree: ***
  13. logop_LeftSemiJoin
  14. logop_Get TBL: A A TableID=213679909 TableReferenceID=0 IsRow: COL: IsBaseRow1002
  15. logop_Get TBL: B B TableID=229679966 TableReferenceID=0 IsRow: COL: IsBaseRow1006
  16. ScaOp_Comp x_cmpEq
  17. ScaOp_Identifier QCOL: [xx].[dbo].[A].SomeColumn
  18. ScaOp_Identifier QCOL: [xx].[dbo].[B].SomeColumn
  19. *******************

猜你在找的MsSQL相关文章