MS SQL Server会随着时间的过去而变慢吗?


8

您是否有以下经历,并且找到了解决方法:

我们网站的后端很大一部分是MS SQL Server2005。每两周或两周,该网站的运行就会开始变慢-我发现使用SQL完成查询所花费的时间越来越长。我有一个喜欢使用的查询:

USE master
select text,wait_time,blocking_session_id AS "Block",
percent_complete, * from sys.dm_exec_requests 
CROSS APPLY sys.dm_exec_sql_text(sql_handle)  AS s2 order by start_time asc

这非常有用……它提供了当时针对SQL Server运行的所有内容的快照。很好的是,即使您的CPU由于某种原因被钉在100%上,并且活动监视器拒绝加载(我确定其中有些人在那里),该查询仍然返回,并且您可以看到哪个查询正在杀死您的数据库。

当我运行此程序时,或者在SQL开始放慢速度的时候运行“活动监视器”,我看不到任何引起该问题的特定查询-它们的运行速度都较慢。如果我重新启动MS SQL Service,那么一切都很好,它可以加快速度-一两个星期,直到再次发生。

我能想到的一切都没有改变,但这只是几个月前才开始的...想法?

- 添加

请注意,发生此数据库速度降低时,无论我们每小时获得10万次页面浏览量(一天中的繁忙时间)还是每小时一万次页面浏览量(缓慢的时间)都没关系,所有查询都比正常完成花费更长的时间。服务器并没有真正处于压力之下-CPU并不高,磁盘使用率似乎并没有失控...这感觉像是索引碎片或类似的东西,但这似乎不是案件。

就我上面粘贴的查询的结果而言,我确实无法做到这一点。上面的查询列出了执行任务的用户的登录名,整个查询等。并且,我真的不想在网上分发数据库,​​表,列和登录名:)...可以告诉您当时运行的查询是正常的,我们的网站一直运行的标准查询,没有任何异常。

-3月24日

自上次重新启动以来已经过去了大约两个星期。我做了几处更改:我发现了一些查询,在这些查询中我们大量使用了临时表,这些表完全没有必要,并且让我们的开发人员更改了他们的工作方式。我将一些不断(缓慢但肯定地)增长的数据库的大小调整为适合其增长的智能大小。我还调整了所有内容的自动增长设置,使其更加智能化(它们都设置为1MB增长)。最后,我整理了一下MSDB。我们进行日志传送,实际上并不需要保留数年之久的备份点,我编写了一些脚本,将其保留了仅几个月。我将继续更新此线程,因为现在判断问题是否已解决还为时过早。


如果通过Management Studio运行相同的查询,是否会遇到与通过应用程序运行相同的性能问题?是什么导致性能下降停止或消失?您重启服务器了吗?这是物理服务器还是VM?它是否拥有自己的存储设备或它是SAN的一部分?
DCNYAM 2010年

网络附加存储,确切地说是MD 3000。重新启动SQL服务将使其消失。是的,您会在这段时间内看到来自工作室的同样慢的响应时间。
戴夫·霍兰

Answers:


3

我们找到了。原来,这实际上是一台Web服务器,其中一个应用程序池有问题。一遍又一遍地运行同一组查询(在临时表中处理)会陷入困境。它将不断循环,最终使SQL Server感到悲伤。一旦找到了这个令人讨厌的机器/应用程序池,并且“放下”了所有东西,就解决了。


2

您必须问自己,SQL服务重启时会发生什么?很多东西,但有两个相关的要点浮现在脑海:

1)SQL内存已释放。

可能的(不知道如何可能),如果你的MaxMemory设置被设置得太高,SQL服务增长到使用所有可用的内存,和Windows开始交换重要的东西出到交换文件。检查并确保将MaxMemory设置为合理的值,为该框上需要运行的其他内容留出足够的额外内存(是专用的SQL Server还是应用程序服务器?)

2)TempDB是从默认大小重建的。

检查默认的tempdb文件大小,尤其是TempDB日志文件的默认大小和增长间隔。如果将增长间隔设置得太低,则日志会建立一些令人难以置信的内部碎片,这可能会大大降低正常使用速度。请参阅Kimberly Tripp撰写的 两篇优秀的博客文章。


1)该计算机是专用的SQL Server,具有16GB的内存,其中有14GB分配给SQL。2)自从对数据库大小和增长进行了一些调整后,我不必重新启动。临时表已包含在我所做的调整中,因此可能会产生一些影响。仅仅过了几周,所以我正在等待情况是否再次发生。
戴夫·荷兰

1

您是否大量使用临时表或游标?检查所有游标是否已关闭并正确释放。还请注意链接的服务器-对于旧的链接的Informix服务器,我们必须使用错误的驱动程序,这意味着我们必须重新启动服务器。


我们确实使用了不少临时表调用,游标我希望大家不要使用过于频繁,但我想这IS可以知道我们的一些旧的编码“标准”,所以我会考虑这样做。我们正在使用链接服务器,但是只有一台,并且将其连接到另一台2005 sql DB。
戴夫·霍兰

0

如果看起来很怪异,那就寻找怪异的东西。

如果调整SQL Server设置无济于事,请尝试Windows任务管理器:转到“进程”选项卡,然后依次选择“选项”>“列”>“添加CPU时间,句柄,读取,写入,其他和内存”选项。

返回到进程列表。对于每个列,按从高到低的顺序排序,并查看前5个过程。有什么不寻常的吗?例如,进程中的内存泄漏将具有异常数量的句柄。我们有一些* ki打印机,每2秒向DCSLoader进程添加一个句柄。几周后,一台机器列出了许多可用内存和cpu,但是一个进程具有100,000个句柄,几乎不会移动鼠标指针。

还要检查您的计划任务列表。告诉您的AV不要扫描.mdf文件。


是的,我已经做了所有事情,进程列表中没有任何异常,并且正如我所说的,我不重新启动计算机..仅重新启动SQL服务,问题就解决了,所以我不太可能继续在SQL Server进程之外查找问题。不过,看一下手柄是个好主意,我下次再检查。
戴夫·霍兰

0

戴夫

您是否查看了等待统计信息?您在上面的查询中列出了“ last_wait_type”列。该列可能包含有关查询正在等待什么的一些详细信息(网络,CPU等)。


我没有,但是我应该。下次再检查。
戴夫·霍兰

0

如果您的备份“恢复模型”为“ FULL”,那么对数据库进行备份再对事务日志进行备份是否会有所改善?在磁盘空间不足的系统上,这种情况可以解释问题。


所有数据库的日志都会每15分钟发送一次-这意味着数据库和事务日志会不断备份,所以这不是问题....它们也都在具有大约TB可用空间的md3K上运行。
戴夫·霍兰

很高兴知道。您的SQL客户端使用哪种方法连接到SQL Server?仍然有很多问题。服务器是64位的吗?
djangofan 2010年

客户端是.net网站(toolbox.com),是64位。
戴夫·荷兰

因此,您的.net客户端是否使用jdbc2.x驱动程序,并且它们是否使用集成身份验证?
djangofan

0

我似乎拥有与您的配置非常相似的配置(16 Gb,已升级到32 Gb,以及具有1 TB磁盘的MD1000,双四核xeon)。

已经帮我诊断一样,在过去的离奇问题的唯一事情是beta_lockinfo通过厄兰Sommarskog。在时间较慢时运行它并进行比较。

另外,在SP2之前的SQL 2005中,我遇到了很多疯狂的问题,但是SP3确实很稳定。


其实,我只是想起了。尝试使用“锁定内存中的页面”。借助SP4的CU4,甚至SQL 2005 Standard也可以使用它。参见blogs.msdn.com/suhde/archive/2009/05/20/…–
里卡多·帕尔迪尼

0

希望这会提供更多有用的信息:

SELECT  D.text SQLStatement,
        A.Session_ID SPID,
        C.BlkBy,
        ISNULL(B.status, A.status) Status,
        A.login_name Login,
        A.host_name HostName,
        DB_NAME(B.Database_ID) DBName,
        B.command,
        ISNULL(B.cpu_time, A.cpu_time) CPUTime,
        ISNULL((B.reads + B.writes), (A.reads + A.writes)) DiskIO,
        A.last_request_start_time LastBatch,
        A.program_name
FROM    sys.dm_exec_sessions A
        LEFT JOIN sys.dm_exec_requests B
        ON A.session_id = B.session_id
        LEFT JOIN (
                   SELECT   A.request_session_id SPID,
                            B.blocking_session_id BlkBy
                   FROM     sys.dm_tran_locks AS A
                            INNER JOIN sys.dm_os_waiting_tasks AS B
                            ON A.lock_owner_address = B.resource_address
                  ) C
        ON A.Session_ID = C.SPID
        OUTER APPLY sys.dm_exec_sql_text(sql_handle) D
WHERE   DB_NAME(B.Database_ID) = 'YourDBName' -- Comment out line for all db's
ORDER BY ISNULL(B.cpu_time, A.cpu_time) + ISNULL((B.reads + B.writes), (A.reads + A.writes)) DESC

确保db正常运行:

DBCC CHECKDB -- Checks the allocation and structural integrity of all the objects in the specified database.
DBCC UPDATEUSAGE (bybox) -- Reports and corrects pages and row count inaccuracies in the catalog views

留意以下日志空间:

DBCC SQLPERF(LOGSPACE)

如果您看到扩展正在进行中,那肯定会减慢速度。如果运行此命令,您将看到日志空间越来越接近100%,则日志将扩大,并且百分比会随着其空间的增加而缩小。希望您在备份​​开始执行并清除日志之前永远不会看到它扩展。


当我运行第一个查询时,我没有得到任何结果-主要是因为实际上并没有阻止在这些缓慢的时间段内发生的会话...只是查询的运行速度通常较慢。我经历了所有的DBCC检查和更新用法,它们看起来不错。就DBCC SQLPERF(LOGSPACE)而言,唯一一个甚至接近100%(75%)的数据库都是模型,并且永远不会发生重大变化,日志记录备份将照顾日志大小。
戴夫·霍兰

-1

主要是白痴配置。发生。

  • 首先,您实际上应该在维护运行中定期运行索引碎片整理。在进行备份之前或之后,将其安排为活动。

  • 其次,不要自动增长数据库,尤其是不要自动收缩数据库。取决于负载,自动增长/自动收缩基本上是自杀设置。

从来没有像这样使SQL Server变慢。您可以在压力很大的时候发布该查询的结果吗?确定您当时没有任何事情会使SQL Server过载吗?


首先要指出的是:我们每周执行一次维护工作(根据表的不同,每天都有一些维护工作),它们对碎片整理进行索引并更新统计信息。如果您拉回索引中的信息,即使速度很慢,它们的碎片也少于2-3%。第二点:我们不会自动收缩-当然。这些数据库保存着不断增加的用户信息/站点内容等(不是一吨……这些不是巨大的数据库),但是如果我不让它们自动增长,它们应该如何足够大?我将在帖子末尾添加一些详细信息,以解决您所说的最后一个问题。
戴夫·荷兰

3
自动增长并不是一件坏事。依靠它,但是启用它比停止数据库的所有更改要好得多,因为它已达到最大大小。
肖恩·霍瓦特

2
按百分比增长通常也不是一件好事。当数据库变大时,5%的增长将比数据库刚开始时大很多。1MB太小,但是您应该根据数据库的大小和使用情况来确定固定的MB增长率。
DCNYAM 2010年

1
自动增长是很糟糕的,因为它会以较小增量的日志将文件聚类。有很多负面影响。support.microsoft.com/kb/315512而是:将文件设置为适当的大小,然后使用填充报告运行常规检查。确保它们不会过度生长。1mb可能是罪魁祸首,顺便说一句...如果在进行维护时必须停止/增长/停止/增长,则您不希望知道性能。
TomTom 2010年

1
只要很少发生,自动增长是无害的。当它变坏时,就是它被用作适当尺寸的替代品,我怀疑这是TomTom 真正的意思。否则,请务必使用它。
Maximus Minimus 2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.