在where子句中使用嵌套查询时的MSSQL性能问题

时间:2014-05-02 13:42:58

标签: sql-server performance subquery where-clause

MSSQL正在做一些我不理解的事情,我希望在这里找到答案。

我有一个小的查询,在where子句中使用了2个子查询:

where TerminatedDateTime between @startdate and @enddate
and Workgroup in (select distinct Workgroup from #grouping)
and Skills in (select Skills from #grouping) 

查询运行正常,但是当我查看执行计划时,请参阅以下内容: http://i.stack.imgur.com/ogkRP.png

查询     从#grouping中选择不同的工作组 有一个结果:“workgroup1”

查询结果有541行,但它仍然提取日期选择中的所有行。如果我删除工作组和技能部分,行数是相同的。 过滤在哈希匹配中完成。 如果我输入选择查询所在的名称,我会看到以下内容:

where TerminatedDateTime between @startdate and @enddate
and Workgroup in ('workgroup1')
and Skills in (select Skills from #grouping) 

http://i.stack.imgur.com/Ydq6C.png

这里选择正确的行数,查询运行得更好。 为什么这样,是否有办法使用子查询运行查询并使其只选择视图中的相关行? 我已经尝试在#grouping表上使用内部联接,但结果相同,它会选择多行。

1 个答案:

答案 0 :(得分:0)

我不确定您在distinct中需要(select distinct Workgroup from #grouping)的原因。

这里的问题是估计没有了。在没有看到整个查询和执行计划XML的情况下,我建议尝试这些替代方案:

  1. 选择workgroupskills到#temp表并加入

  2. option(recompile)添加到语句

  3. 每一个都应该是一个解决方案。

    无论如何都要看到执行计划XML是有益的。

    编辑(在审查执行计划之后,thx使其可用):

    此查询位于分区视图上。有了检查约束,我们可以看到根据@startdate和@enddate参数的运行时值正确地完成了分区消除。

    为什么优化器为第一个(一个带有子查询)和第二个(一个带有标量)查询生成不同的执行计划?

    就优化器而言,子查询只生成一行只是巧合。它必须创建一个执行计划,该计划对子查询的任何输出都有效,无论是一行,一行还是多行。

    OTOH,当你指定一个标量值时,优化器可以自由地做出更直接的决定。

    使用分区视图使得优化器的工作更加困难,因此我的原始建议显示无用。

    是的,优化器可能在这里做得更好。顺便说一句,工作组和技能是否有任何相关性?