Lev*_*sen 11 performance sql-server query-performance
我们的 MS SQL Server 使用了大约 95% 的 CPU 功率。
服务器(硬件)重启或 SQL-Service 重启后,使用率为 0%,并在 1-3 天的过程中缓慢增加。取决于它的使用量。
当它超过 80% 时,每个查询都非常慢。
我们的网站正在处理大量大型查询,因此其中一些需要 45-60 秒。重启后(CPU使用率低于80%),同一个Query需要11-20秒。
我怎样才能解决这个问题?我在网上读到亲和掩码可以调整 CPU 使用率,但亲和设置被禁用。我无法改变它们。这是因为我只有 1 个处理器吗?
查询本身有很多技巧,但我们的网站和服务相当大,要改变的地方太多了。
他们中的大多数已经得到了很好的优化。
我不能一直重新启动 SQL-Service,即使它只需要 2 秒钟,因为我们有一个警报服务,允许人们呼叫并录制消息,然后将呼叫选定的组并听到录制的消息。
这个系统被数百个搜救队使用,如果 SQL-Service 在警报期间重新启动,它将终止并且不会通知调用它的人。
我找遍了所有地方,除了关于“亲和面具”的东西之外什么也没找到,我无法改变。
必须有一种方法可以清除 CPU 缓存,而不终止当前查询......对吗?
SQL: Microsoft SQL Server 11.0.2100.60
OS: Windows Server 2012 x64
Processor: 2.30 GHz
RAM: 4.00 GB
Run Code Online (Sandbox Code Playgroud)
Aar*_*and 18
Affinity 不会“调整 CPU 使用率”(例如,在您的情况下使 CPU 执行较少的工作),它允许您关闭 CPU(可能使其可用于同一台机器上的另一个实例)或将 CPU 设置为仅辅助 I/O。即使您有多个 CPU,您也无法使用前者来帮助您实现目标,而我们也无法猜测后者,因为我们不知道是什么导致您的 CPU 使用率如此之高。这可能是由于极差的索引、过度编译、大量标量 UDF、I/O 抖动,谁知道?(I/O 可能是原因是,如果您的数据库大于 3 GB 左右,它将不断地将数据交换进和交换出缓冲池内存,这会对 CPU 产生影响。)
CPU 缓存也是一个您不需要深入的兔子洞。由于 CPU 缓存问题,我非常怀疑您的 CPU 是否以 95% 的速度运行。
为了帮助缩小 CPU 压力的来源,并假设您正在使用存储过程,您可以查看 Glenn Berry(来自此处)的诊断查询- 确保在正确的数据库上下文中运行它:
-- Top Cached SPs By Total Worker time (SQL Server 2012).
-- Worker time relates to CPU cost (Query 44) (SP Worker Time)
SELECT TOP (25)
p.name AS [SP Name],
qs.total_worker_time AS [TotalWorkerTime],
qs.total_worker_time/qs.execution_count AS [AvgWorkerTime],
qs.execution_count,
ISNULL(qs.execution_count/DATEDIFF(Second, qs.cached_time, GETDATE()), 0)
AS [Calls/Second],
qs.total_elapsed_time,
qs.total_elapsed_time/qs.execution_count AS [avg_elapsed_time],
qs.cached_time
FROM sys.procedures AS p WITH (NOLOCK)
INNER JOIN sys.dm_exec_procedure_stats AS qs WITH (NOLOCK)
ON p.[object_id] = qs.[object_id]
WHERE qs.database_id = DB_ID()
ORDER BY qs.total_worker_time DESC OPTION (RECOMPILE);
-- This helps you find the most expensive cached stored procedures from a CPU perspective
-- You should look at this if you see signs of CPU pressure
Run Code Online (Sandbox Code Playgroud)
如果您不使用存储过程,那么来自 John Samson 的这个示例可以帮助隔离即席查询(来自此处):
SELECT TOP (25)
qs.sql_handle,
qs.execution_count,
qs.total_worker_time AS Total_CPU,
total_CPU_inSeconds = --Converted from microseconds
qs.total_worker_time/1000000,
average_CPU_inSeconds = --Converted from microseconds
(qs.total_worker_time/1000000) / qs.execution_count,
qs.total_elapsed_time,
total_elapsed_time_inSeconds = --Converted from microseconds
qs.total_elapsed_time/1000000,
st.text,
qp.query_plan
FROM sys.dm_exec_query_stats AS qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) AS st
CROSS apply sys.dm_exec_query_plan (qs.plan_handle) AS qp
ORDER BY qs.total_worker_time DESC OPTION (RECOMPILE);
Run Code Online (Sandbox Code Playgroud)
您还可以查看 Adam Machanic 的sp_WhoIsActive,这是一个可以快速分析所有当前正在运行的查询的存储过程,并允许您根据需要对其进行排序(例如在您的情况下@sort_order = '[CPU] DESC')。
不过,我会做的第一件事——特别是如果这对搜救队来说真的是关键任务——是购买更好的硬件。您应该拥有更多 CPU 和更多 RAM 来为您的应用程序提供服务。您还绝对需要更好的高可用性(例如集群、镜像或可用性组)。没有理由重启物理机会使您的应用程序完全脱机 - 我们有更好的解决方案来解决这个问题。最后,我假设这个“服务器”只有一个旋转磁盘驱动器。这意味着所有 I/O - 来自操作系统、SQL Server 数据文件、日志文件、tempdb 等都通过单个控制器并在单个驱动器上共享读/写活动。获取更多磁盘。如果/在可能的情况下获取 SSD。使用 RAID 并尽量分散 I/O。
话虽如此,将硬件投入问题并不是解决问题的唯一部分。无论您使用何种硬件,您都需要准确隔离导致 CPU 使用率过高的原因,然后解决这些问题。
另请参阅此 StackOverflow 问题以了解其他一些想法:
小智 7
这是一个长镜头,但您可能想看看您的强制参数化设置。如果您在性能不佳时看到大量查询计划,则您的查询没有按照您期望的方式缓存,并且查询需要很长时间来扫描缓存以查看是否有计划已使用。如果清除缓存解决了这个问题,您可能需要考虑更改强制参数化设置。您可以使用以下方法清除缓存:
DBCC FREEPROCCACHE
Run Code Online (Sandbox Code Playgroud)
如果通过以下方式清除缓存,您可以检查强制参数化设置是什么:
SELECT name
, is_parameterization_forced
FROM sys.databases;
Run Code Online (Sandbox Code Playgroud)
这可能设置为默认值 0。如果他们愿意,您可以通过执行以下操作将其设置为 true:
ALTER DATABASE [database_name] SET PARAMETERIZATION FORCED;
Run Code Online (Sandbox Code Playgroud)
这应该首先在开发环境中完成,看看这是否会以其他方式对数据库产生负面影响。可以使用以下方法恢复它:
ALTER DATABASE [database_name] SET PARAMETERIZATION SIMPLE;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
88741 次 |
| 最近记录: |