作为我正在进行的压力测试的一部分,我试图弄清楚是否有一个 SQL 查询(特别是 SQL Server 查询)会将所有 CPU 使用率最大化到 100% 或足够接近。
有人有建议吗?
SELECT SUM(CONVERT(BIGINT, o1.object_id) + CONVERT(BIGINT, o2.object_id) + CONVERT(BIGINT, o3.object_id) + CONVERT(BIGINT, o4.object_id))
FROM sys.objects o1
CROSS JOIN sys.objects o2
CROSS JOIN sys.objects o3
CROSS JOIN sys.objects o4
这是一个并行版本:
USE master
SELECT MyInt = CONVERT(BIGINT, o1.object_id) + CONVERT(BIGINT, o2.object_id) + CONVERT(BIGINT, o3.object_id)
INTO #temp
FROM sys.objects o1
JOIN sys.objects o2 ON o1.object_id < o2.object_id
JOIN sys.objects o3 ON o1.object_id < o3.object_id
SELECT SUM(CONVERT(BIGINT, o1.MyInt) + CONVERT(BIGINT, o2.MyInt))
FROM #temp o1
JOIN #temp o2 ON o1.MyInt < o2.MyInt
由于某种原因,我无法让优化器并行化第一个查询。所以我只是具体化一些巨大的表(~400k 行)并循环连接它们。
我在如何分析 SQL Server 性能中详细讨论了为什么你的查询实际上从不“执行”:总是在某些事情上等待(IO、锁)。
创建一个驱动 100% CPU 的工作负载,即使是在一个核心上,也是一项不小的壮举。您需要确保您的查询始终执行并且从不等待。从不阻塞 IO(所有数据必须在内存中),从不阻塞锁(无争用),从不阻塞内存(无授权)。您应该将其视为内存中热数据的扫描。实现这一点的人为的、完全伪造的工作负载可能会多次自连接一个中等大小的表。
现在,如果您想以实际的工作负载(包括各种操作)来完成此操作,那么祝您好运。实现 100% CPU 基本上是基准测试的黄金标准。您需要超高性能的 IO 子系统来消除所有等待,并且需要非常奇特的测试驱动程序才能足够快地提供工作负载,而不会产生争用。
我认为保持 CPU 忙碌的更好方法是在所有编译器中使用 POWER 函数
DECLARE @T DATETIME, @F BIGINT;
SET @T = GETDATE();
WHILE DATEADD(SECOND,60,@T)>GETDATE()
SET @F=POWER(2,30);
您可以同时运行多个查询,具体取决于您的 CPU 容量
看看下面的这个链接(原创文章)
https://blog.sqlauthority.com/2013/02/22/sql-server-t-sql-script-to-keep-cpu-busy
这个想法来自usr,使它更通用一点,没有使用SQL Server特有的东西,所以你可以将它用于任何类型的DB/DM。而且没有写,这样可以避免I/O影响。
首先需要选择一个大用途或系统表“table1”。
如果该表有 N 条记录,则以下查询会产生 O(N^4) 复杂度,优化器无法改进它。
with t1 as
(
select
d1.f1 as i1, d2.f1 as i2, d3.f1 as i3, d3.f2 as f2
from
table1 d1
inner join
table1 d2 on d1.f1 < d2.f1
inner join
table1 d3 on d2.f1 < d3.f1
order by
f2
)
select
avg(sin(o1.i1)) + avg(cos(o2.i1))
from
t1 o1
join
t1 o2 on o1.i1 < o2.i1
这是一个非常古老但有趣的问题,但与此处列出的所有其他解决方案相比,此链接(来自 Brent Ozar)是最佳解决方案
https://www.brentozar.com/archive/2018/09/one-hundred-percent-cpu/