jam*_*c86 2 sql-server sql-server-2012
我有一个使用 SQL Server 2012 Enterprise Edition 作为后端的 Web 系统。
我们的一个查询特别繁重,大约需要 60 秒。我对这个查询进行了大量分析,知道时间花在了 INSERT INTO 表变量 SELECT FROM 表中。这意味着表上应该有一个共享锁,但并行进程应该能够并行运行此查询。
一个 Web 端点在不同的进程中并行调用其中 3 个过程。由于我们有 4 个内核,我希望 SQL 服务器应该在一个内核上运行一个进程,因此 3 个进程同时运行,这样我们的查询时间约为 60 秒。
然而,大多数情况下,它会在运行 2 个进程之间切换,然后每 20-30 秒运行 1 个进程。我可以看到 CPU 使用率在 25% 到 50% 之间跳跃(因为是 4 核机器)。
未运行的进程处于 RUNNABLE 状态,因此它们似乎只是在等待 CPU 时间,没有导致问题的表锁。
有时它实际上一次只运行 1 个,有时同时运行 3 个,因此某些事情会导致一些决策。
我已经检查过许可看到所有 4 个核心(确实如此)并且处理器关联设置为全部使用。由于这不在查询中,我不希望 MAX_DOP 对此产生影响,但我已在 0 和 2 处尝试过。
知道是什么影响了 SQL 服务器的决策制定吗?如果我们可以改变这种行为?
首先,将数据插入表变量是单线程的(不是并行的)。您可以在 Paul White 的史诗文章Fording a Parallel Execution Plan 中了解更多相关信息。
其次,当您运行多个查询时,您无法预测哪些查询将在哪些内核上结束。传入的查询被分配给一个工作程序,该工作程序固定在一个调度程序上,该调度程序在 CPU 内核上运行。SQL Server 事先不知道查询(或多个查询)的复杂程度,因此它无法预测性地进行负载平衡。如果您真的想让 CPU 达到 100%,您将需要运行 3 个以上的查询,或者您需要检查 DMV 以中止您的查询,如果它们最终在同一个调度程序上。
或者做我会做的 - 停止使用表变量并切换到临时表。
归档时间: |
|
查看次数: |
266 次 |
最近记录: |