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.

我通过使用 Set Operation 重写了查询 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 Time 是 Elapsed time 的 2 倍以上

我搜索这个案例,大多数人说 CPU time 应该小于 Elapsed time,因为 CPU time 是 CPU 运行这个任务的时间。Elapsed time 包括 I/O 时间和其他类型的时间成本。但一种特殊情况是服务器有多个核心 CPU。但是,我刚刚检查了开发数据库服务器,它有一个单核 CPU。

问题 1

如何解释单核 CPU 环境中查询 A 中的 CPU 时间超过 Elapsed time?

问题2

之后,使用set操作,性能真的提升了吗?

我有这个问题是因为查询 B 的逻辑读取为 280627,高于查询 A 的 241885

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

比,它是否正确地说即使查询 B 具有比查询 A 更高的逻辑读取,但 CPU 时间明显少于查询 A,查询 B 应该具有更好的性能。

4

2 回答 2

10

如果 CPU 大于 elapsed,则您确实拥有多核或超线程 CPU

CPU 时间是安装 SQL Server 引擎的地方。它不适用于本地 Management Studio 安装。

至于逻辑 IO 与 CPU,我会选择较低的 CPU。如果这经常运行且重叠,您将首先耗尽 CPU 资源。我会尝试 WHERE EXISTS (UNION ALL) 构造并确保我有良好的索引。

编辑,评论后

  • 计划中有并行运算符 = OS 和 SQL Server 可以看到多个逻辑处理器。所以它要么是多核的,要么是超线程的

试试EXEC xp_msver

于 2011-06-21T04:25:50.427 回答
2

在我的情况下 - SQL Server 执行时间:CPU 时间 = 671 毫秒,经过时间 = 255 毫秒。

CPU 时间几乎是查询所用时间的三倍。由于查询是并行处理的,CPU 负担非常高,CPU 可能成为这种场景的瓶颈。

SQL Server 2012 为 CPU 负担问题带来了解决方案。它引入了一次处理成批行的迭代器,而不仅仅是逐行处理。

对于查询优化,您可以在表上创建列存储索引-

在 dbo.Tablename(feild1,feild2) 上创建列存储索引 idx_cs_colname;

于 2014-07-22T13:31:16.153 回答