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表上使用内部联接,但结果相同,它会选择多行。
答案 0 :(得分:0)
我不确定您在distinct
中需要(select distinct Workgroup from #grouping)
的原因。
这里的问题是估计没有了。在没有看到整个查询和执行计划XML的情况下,我建议尝试这些替代方案:
选择workgroup
和skills
到#temp表并加入
将option(recompile)
添加到语句
每一个都应该是一个解决方案。
无论如何都要看到执行计划XML是有益的。
编辑(在审查执行计划之后,thx使其可用):
此查询位于分区视图上。有了检查约束,我们可以看到根据@startdate和@enddate参数的运行时值正确地完成了分区消除。
为什么优化器为第一个(一个带有子查询)和第二个(一个带有标量)查询生成不同的执行计划?
就优化器而言,子查询只生成一行只是巧合。它必须创建一个执行计划,该计划对子查询的任何输出都有效,无论是一行,一行还是多行。
OTOH,当你指定一个标量值时,优化器可以自由地做出更直接的决定。
使用分区视图使得优化器的工作更加困难,因此我的原始建议显示无用。
是的,优化器可能在这里做得更好。顺便说一句,工作组和技能是否有任何相关性?