SEa*_*986 2 parallelism sql-server-2016 query-performance
我有一个 SQL Server 查询如下(混淆):
UPDATE [TABLE1]
SET [COLUMN1] = CAST('N' AS CHAR(1))
FROM [TABLE1]
WHERE (COLUMN1 = '2' AND COLUMN2 IN('VAL1', 'VAL2', 'VAL3')) OR
(COLUMN1 <> 'N' AND (
SELECT COUNT(*)
FROM TABLE2 wle
JOIN TABLE3 wl
ON wl.COLUMN3 = wle.COLUMN3
WHERE TABLE1.COLUMN4 = wle.COLUMN4 AND
(wl.COLUMN5 = '1' OR wl.COLUMN6 = '1') AND
wle.COLUMN7 = (
SELECT MIN(alias.COLUMN7)
FROM TABLE2 AS alias
WHERE TABLE1.COLUMN4 = alias.COLUMN4
)
) > 0
)
Run Code Online (Sandbox Code Playgroud)
我们刚刚将我们的(测试)服务器从 SQL Server 2014 SP3 升级到 SQL Server 2016 SP2。
因此,上述查询的性能似乎已经下降。
服务器在SQL Server 2014的时候,数据库兼容级别是120,现在在SQL Server 2016,数据库兼容级别还是120,但是我试过110120和130的查询,结果都是一样的.
当我运行时sp_whoisactive
,我可以看到 wait_info(48847425ms)CXCONSUMER
提示查询一直在等待CXCONSUMER
最后一次48847425ms
(814 分钟) 查询当前已运行 13:34:07.587。
等待信息表明该查询已经等待CXCONSUMER
了大多数(如果不是全部)执行时间。
这对我来说表明并行性存在一些问题,因此我使用提示运行查询OPTION (MAXDOP 1)
并在可接受的时间内完成(大约 30 秒)
计划形状如下。
MAXDOP 1
查询的计划形状如下:
(没有并行操作符的相同计划)
当我在启用实时执行计划的情况下运行并行查询时,以绿色突出显示的运算符(聚集索引扫描打开TABLE2
)显示 100%,但它的执行时间继续计时。
以红色突出显示的运算符(Clustered Index Scan on TABLE1
)在 180,215 的 4 行上“卡住”。
什么可能导致这个问题?在我的脑海中,我认为这是并行性倾斜(不均匀的工作量),但鉴于串行查询在不到一分钟的时间内完成,我会认为即使查询并行但只使用一个线程,它仍然会在接近的时间内完成串行查询。此外,鉴于实时计划似乎显示红色聚集索引扫描根本没有进展,我不确定发生了什么。
处理器和 I/O 关联设置为自动
我发现这篇文章描述了类似的行为,尽管文章的目的似乎表明 CXCONSUMER 不一定是良性等待,并且没有说明如何/是否可以修复它。
在修复它方面,我知道可以以更有效的方式重新编写代码(可以将查询COUNT
和MIN
子查询都选择到变量中),但不幸的是,更改查询不是我的选择。我可以强制MAXDOP
提示,但同样,这意味着更改代码,也许我可以用计划指南强制它,尽管这种强制优化器的做法通常是不可取的?
是什么导致了这个问题?
为什么查询在 SQL Server 2016 中运行缓慢?
为什么 TABLE1 上的聚集索引扫描在 180,215 的 4 行上“卡住”?
有没有办法在不更改代码的情况下解决这个问题?
有没有办法在不更改代码的情况下解决这个问题?
创建以下索引以消除急切索引假脱机:
-- Give this index a better name
CREATE INDEX i ON dbo.TABLE2 (COLUMN4, COLUMN7) INCLUDE (COLUMN3);
Run Code Online (Sandbox Code Playgroud)
有了这个,你应该得到一个类似于以下的计划:
一旦您为优化器提供了良好的索引,问题中描述的其他问题几乎肯定会消失。
这是可能的(虽然不太可能)从你的查询患有未被发现查询内并行的死锁(IQPD)。需要进行非常详细的调查才能确认这一点。绝大多数 IQPD都被检测到,然后可以通过将交换缓冲区溢出到tempdb来解决。未检测到的 IQPD 将导致查询永远卡住。
归档时间: |
|
查看次数: |
206 次 |
最近记录: |