SQL Server在占用全部内存后完全变慢
在具有32 GB RAM的服务器上,我们有一个SQL server实例正在运行,最大内存上限为80% 内存利用率低时,一切正常。请参见下面的屏幕截图 但随着时间的推移,SQL将在3-4天内使用完整的RAM(占总RAM的80%) 在这3-4天内,我们没有对服务器进行任何更改,但它一天比一天消耗更多的内存 当它达到最大限制时,整个性能将受到影响,我们的网站将面临查询超时。执行毫秒内执行的同一查询需要许多秒 此时,我们别无选择,只能重启整个服务器,一切恢复正常。(仅重新启动服务不起作用) 这将工作一周左右,之后我们必须重新启动它 我在网上读到,SQL server不会释放内存。但他们也提到,这是SQL的工作方式,但并不影响性能。 在我的例子中,它确实如此,性能受到影响SQL Server在占用全部内存后完全变慢,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,在具有32 GB RAM的服务器上,我们有一个SQL server实例正在运行,最大内存上限为80% 内存利用率低时,一切正常。请参见下面的屏幕截图 但随着时间的推移,SQL将在3-4天内使用完整的RAM(占总RAM的80%) 在这3-4天内,我们没有对服务器进行任何更改,但它一天比一天消耗更多的内存 当它达到最大限制时,整个性能将受到影响,我们的网站将面临查询超时。执行毫秒内执行的同一查询需要许多秒 此时,我们别无选择,只能重启整个服务器,一切恢复正常。(仅重新启动服务不起作用) 这将工作一
有内存泄漏吗?或者一个存储的进程消耗大量内存却从不释放它?如果是,如何调试它?默认情况下,如果取消上限,SQL server将消耗整个内存,并在封顶时使用所有可用内存。这是正常的。您还必须确保SQL server是框中唯一的应用程序(建议使用)和 我将使用以下方法开始故障排除 1.开始查找最消耗内存的查询,看看是否可以减少查询的内存使用量..可以通过下面的查询找到消耗内存的查询
SELECT TOP 10 SUBSTRING(qt.TEXT, (qs.statement_start_offset/2)+1,
((CASE qs.statement_end_offset
WHEN -1 THEN DATALENGTH(qt.TEXT)
ELSE qs.statement_end_offset
END - qs.statement_start_offset)/2)+1),
qs.execution_count,
qs.total_logical_reads, qs.last_logical_reads,
qs.total_logical_writes, qs.last_logical_writes,
qs.total_worker_time,
qs.last_worker_time,
qs.total_elapsed_time/1000000 total_elapsed_time_in_S,
qs.last_elapsed_time/1000000 last_elapsed_time_in_S,
qs.last_execution_time,
qp.query_plan
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) qt
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
ORDER BY qs.total_logical_reads DESC -- logical reads
-- ORDER BY qs.total_logical_writes DESC -- logical writes
-- ORDER BY qs.total_worker_time DESC -- CPU time
既然您发现查询会导致高内存,那么您需要对它们进行微调,看看是否可以减少内存使用
例如:查询可能由于索引不合适而进行了多次读取,或者可能是您的IO设备由于缓冲池被多次刷新而出现问题
2.您还可以找到使用内存的顶级组件,这让您了解RAM是如何使用的
SELECT TOP(20) [type], [name], SUM(single_pages_kb) AS [SPA Mem, Kb]
FROM sys.dm_os_memory_clerks
GROUP BY [type], [name]
ORDER BY SUM(single_pages_kb) DESC;
若缓冲池一致地使用更多的内存,我不会担心这一点,但若它是cachestore_obcp,那个么您可能会有许多临时查询填满了缓存存储,这是不好的
调查的一部分会导致另一部分,因此您必须根据线索进行故障排除,因为没有一键解决方案
旁注:不推荐:我们的一个dev实例曾经遇到过同样的问题,因此我们没有做所有的调优工作,而是使用下面的命令来立即有效地释放内存。但对于生产实例来说,这一点都不推荐,因为这会刷新缓存中存储的计划,并且您可能会面临轻微的CPU压力
DBCC FREEPROCCACHE WITH NO_INFOMSGS;
参考文献: