我们的Web应用程序的数据库服务器存在问题,在非常短的时间内(<10毫秒)运行的查询在随机的情况下需要花费1到30秒才能执行 - 没有明显的模式.根据我们的探查器跟踪,其中一些甚至是“无所事事”查询,例如“exec sp_reset_connection”(通常以0ms运行;观察到3~6s的峰值)和“SET NO_BROWSETABLE ON”等.一些例子是:
SELECT * FROM [Localisation].[TimeZoneRule] WHERE [Name] = 'EU'
TimeZoneRule在5列中有大约500,000行.具有代理主键和Name上的索引.通常需要0.97ms,峰值为11s.表永远不会写入(在上线之前预先填充). Profiler将其记录为0-15 cpu,18-25读取,0-1写入(不知道为什么写入).
UPDATE [Core].[User] SET [LastUsed] = GETUTCDATE() WHERE Id = '<uid>'
用户在大约10列(其中一列是Xml列)上有大约30,000行. Id是群集主键.表定期写入和读取.通常需要10~20ms,峰值为26s. Profiler将其记录为0 cpu,15-36读取,0-1写入.
INSERT INTO [Log].[Session] (ASPSessionId,Start,ClientAddress,ClientSoftware,ProxyAddress,ProxySoftware) VALUES(<number>,GETUTCDATE(),'<ipv4address>','<User agent string>','<proxy software name (if present)>')
Session在大约8列中有大约1,000,000行.具有代理主键(标识)和ASPSessionId上的索引.表定期写入,但很少从中读取(仅由我们直接从SSMS读取).通常需要15~150ms,峰值为5s.我手头没有配置文件记录,但是从内存来看,cpu大约是0,读取和写入都在0到100之间.
我们使用的设置是镜像设置,以Dell 2950为原则(2个4核xeon 2.6,16Gb RAM)和戴尔6850作为镜像(4 HT Xeon 3.2,8Gb RAM).两者都运行sql 2005 SP4 64位.有问题的数据库并不是特别大,大小约为16Gb.主要有6个SAS磁盘,分为3个RAID-1卷;一个用于System Page TempDB,一个用于数据库的MDF,另一个用于事务日志每小时日志备份每日数据库备份.我知道日志情况远非最好 – 在磁盘IO(见下文)和数据安全性方面.
到目前为止,我们认为我们已经淘汰了:
>镜子.我们将服务器分开,并使用其中一个(然后切换到另一个)运行,但性能问题仍然存在.
>由于锁定(*)而阻塞.永远不会写入TimeZoneRule,并且通过我的计算,永远不应该对它进行独占锁定.此外,我们已经检查了跟踪,并且在很多情况下“问题查询”是唯一运行的 – 唯一的其他活动是其他连接断开连接
>索引不佳.由于读取和cpu的数字较低,这表明sql Server正在有效地使用索引.
>磁盘IO. PerfMon表示数据文件驱动器的一些奇数(但只有那个驱动器) – 虽然数据读/写速率似乎很少超过32KB / s,但当前磁盘队列长度在大约45秒时持续2-5秒达到215左右. -60分钟间隔,没有固定模式.但是,这些与查询性能不佳的时间无关.其他两个驱动器[系统页面tempdb]和[日志备份]的磁盘队列长度
永远不会超过3.
(*)我们尝试使用分析器捕获与锁定获取相关的事件,但是跟踪膨胀到不可读的比例,更糟糕的是,Web应用程序停止运行.
不是DBA,我们很快就会缺乏想法.任何人都可以想到我应该考虑下一个或者我愚蠢地错过的任何事情吗?
解决方法
磁盘队列峰值永远不会好.特别是那么高.当队列变得那么高时,你要推送到磁盘的IO是什么?基本上,您不希望磁盘队列高于(2 * n),其中数组中的磁盘数为n.由于您使用的是2磁盘RAID 1 n = 1(因为您只获得单个磁盘的速度).
在perfmon中有一个计数器,即每次读取的秒数和每次写入的秒数.当查询开始花费很长时间运行时,这些计数器是什么样的.通常怎么样? (超过.02秒的任何事情都很糟糕.)估计的页面预期寿命是多少? (300秒以下的任何内容通常都很糟糕,但这可能会有所不同.)sql Server缓存命中率是多少? (低于97%的任何东西通常都是坏的.我喜欢我的99.9%以上.)