SQL Server查询优化:为什么CPU时间比经过时间高?它们与设置操作相关吗?

8
我有两个查询,根据问题和答案过滤一些用户ID。
场景:
查询A是(原始版本):
SELECT userid
FROM mem..ProfileResult
WHERE ( ( QuestionID = 4
          AND QuestionLabelID = 0
          AND AnswerGroupID = 4
          AND ResultValue = 1
        )
        OR ( QuestionID = 14
             AND QuestionLabelID = 0
             AND AnswerGroupID = 19
             AND ResultValue = 3
           )
        OR ( QuestionID = 23
             AND QuestionLabelID = 0
             AND AnswerGroupID = 28
             AND ( ResultValue & 16384 > 0 )
           )
        OR ( QuestionID = 17
             AND QuestionLabelID = 0
             AND AnswerGroupID = 22
             AND ( ResultValue = 6
                   OR ResultValue = 19
                   OR ResultValue = 21
                 )
           )
        OR ( QuestionID = 50
             AND QuestionLabelID = 0
             AND AnswerGroupID = 51
             AND ( ResultValue = 10
                   OR ResultValue = 41
                 )
           )
      )
GROUP BY userid
HAVING COUNT(*) = 5

我使用“set statistics time on”和“set statistic io on”来检查CPU时间和IO性能。
结果是:
CPU time = 47206 ms,  elapsed time = 20655 ms.

我通过使用集合操作重写了查询A,让我把它命名为查询B:
SELECT userid
FROM ( SELECT userid
        FROM mem..ProfileResult
        WHERE QuestionID = 4
            AND QuestionLabelID = 0
            AND AnswerGroupID = 4
            AND ResultValue = 1
       INTERSECT
       SELECT userid
        FROM mem..ProfileResult
        WHERE QuestionID = 14
            AND QuestionLabelID = 0
            AND AnswerGroupID = 19
            AND ResultValue = 3
       INTERSECT
       SELECT userid
        FROM mem..ProfileResult
        WHERE QuestionID = 23
            AND QuestionLabelID = 0
            AND AnswerGroupID = 28
            AND ( ResultValue & 16384 > 0 )
       INTERSECT
       SELECT userid
        FROM mem..ProfileResult
        WHERE QuestionID = 17
            AND QuestionLabelID = 0
            AND AnswerGroupID = 22
            AND ( ResultValue = 6
                  OR ResultValue = 19
                  OR ResultValue = 21
                )
       INTERSECT
       SELECT userid
        FROM mem..ProfileResult
        WHERE QuestionID = 50
            AND QuestionLabelID = 0
            AND AnswerGroupID = 51
            AND ( ResultValue = 10
                  OR ResultValue = 41
                )
     ) vv;

CPU时间和经过时间为:
CPU time = 8480 ms,  elapsed time = 18509 ms

我的简单分析

从上面的结果可以看出,查询A的CPU时间比经过时间长了两倍以上。

我搜索了一下这种情况,大多数人都说CPU时间应该小于经过时间,因为CPU时间是CPU运行此任务所需的时间。而经过时间包括I/O时间和其他类型的时间成本。但有一种特殊情况是当服务器具有多个核心CPU时。然而,我刚刚检查了开发数据库服务器,它只有一个单核心CPU。

问题1

如何解释在单核心CPU环境中查询A的CPU时间大于经过时间?

问题2

使用集合操作后,性能真的得到了改善吗?

我之所以有这个问题,是因为查询B的逻辑读取次数为280627,比查询A的241885要高。

Brad McGehee在他的文章中说:“查询执行的逻辑读取次数越少,它就越有效率,执行速度也就越快,假设所有其他条件相同。”

那么,即使查询B的逻辑读取次数比查询A高,但CPU时间显着少于查询A,那么查询B应该具有更好的性能。


你的CPU配备了一个通量电容器,可以比时间更快地运行。这里没有幽默的空间吗?显然是CPU任务调度程序或数据库程序中的一个错误。1核CPU是否看起来像2个虚拟CPU? - Daniel Teichman
不,只有一个单核 CPU,也没有虚拟 CPU。 - Jeff Chen
那不应该是可能的。服务器必须认为它有多个CPU。 - Daniel Teichman
2个回答

10
如果CPU时间大于已流逝的时间,则您确实拥有多核或超线程CPU。
CPU时间是安装SQL Server Engine的地方。这不适用于本地管理工具安装。
至于逻辑IO与CPU,我会选择更低的CPU。如果此操作频繁重叠,您将首先耗尽CPU资源。我会尝试使用WHERE EXISTS(UNION ALL)构造并确保我有良好的索引。
编辑后的评论:
  • 计划中有并行性运算符=操作系统和SQL Server可见的多个逻辑处理器。因此,它要么是多核心,要么是超线程。
尝试EXEC xp_msver

嗨,gbn,是的,执行计划中有两个并行性。这是否意味着服务器具有多个核心或其他信息? - Jeff Chen
我刚刚回去查看了执行计划。查询A和查询B都有并行性(收集流)。然而,我去MSDN上查找关于并行性的词语,它说并行性是为多处理器而设计的。那么我真的无法弄清楚这里发生了什么... - Jeff Chen
1
尝试执行EXEC xp_msver。答案已更新。 - gbn
1
@JeffChen:任务管理器上的CPU使用率仪表总是只显示一个条形图,无论你有多少个CPU。如果一个CPU达到最大值而另一个处于空闲状态,则它将显示50%。如果两个CPU都达到最大值,则它将显示100%。 - siride
@gbn 你能指出一些与该行为相关的官方文档或规格说明吗? - Ehsan Sajjad
显示剩余3条评论

2
在我的情况下,SQL Server 执行时间如下:CPU 时间 = 671 毫秒,经过时间 = 255 毫秒。 查询的 CPU 时间几乎是经过时间的三倍。由于查询是并行处理的,CPU 负担非常高,因此 CPU 可能成为此场景的瓶颈。
SQL Server 2012 提供了解决 CPU 负担问题的方法。它引入了迭代器,可以一次处理多个行而不仅仅是一行。
为了查询优化,您可以在表上创建列存储索引: CREATE COLUMNSTORE INDEX idx_cs_colname ON dbo.Tablename(feild1,feild2);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接