SQLS 超时 - Profiler 中的高读取次数

SQLS 超时 - Profiler 中的高读取次数

我用 Profiler 审计了一台 SQLS2008 服务器一天……我公司的新客户似乎没有遇到开销问题。他们使用旧版 VB6 应用程序作为前端。一旦 SQLS RAM 使用率过高,他们就会遇到超时。该服务器当前在具有近 9 GB RAM 的 VM 上运行 x64 sqls2008。SQL Server 的“最大服务器内存选项”当前设置为 6GB。

我把跟踪的结果放在一个表中,并使用此查询对其进行了查询。

从 [TraceWednesday] 中选择 TextData、ApplicationName、Reads,
其中 textdata 不为空且 EventClass = 12 按 TextData、ApplicationName、Reads 分组 按 Reads DESC 排序

正如我所料,一些值非常高。

Top Reads, in pages.
2504188
1965910
1445636
1252433
1239108
1210153
1088580
1072725

我认为最上面的一个 (2504188 页) 是 20033504 KB,大约是 ~20'000 MB,20GB,对吗?这些查询经常执行,并且可能需要相当长的时间才能运行。最终,由于缓存膨胀,RAM 被用完,并且一旦 SQL 无法在缓冲池中“溅射”页面,就会发生超时。成本上升。我的理解正确吗?

我读到过我应该调整相关的 T-SQL 并创建适当的索引。显然,减少 I/O 会使 SQL Server 使用更少的 RAM。或者,也许它只是减慢了消耗整个 RAM 的过程。如果读取的页面少了很多,也许即使使用率很高,它也会运行得更好?(更少的时间交换等)

目前,我们唯一的选择是每周在 RAM 使用率较高时重启一次 SQL,超时问题突然消失。SQL 再次恢复活力。

我确信很多 DBA 都遇到过这种情况。我想问一下,在我开始找出所有糟糕的 T-SQL 并到处放置索引之前,我还能做些什么吗?除了我所知道的(目前还不多)之外,还有什么建议吗?

非常感谢,
Leo。

答案1

一般来说,SQL Server 会分配尽可能多的内存,而不使用分页文件。这些内存用作数据页的缓存。(还有一个计划缓存和一些其他内容,但我认为这超出了这个问题的范围。)这种分配会“用尽”服务器上的所有可用内存,这常常让不熟悉 SQL Server 的人感到担忧。

不要担心内存量,而要担心物理页面读取(来自磁盘)和逻辑页面读取(来自内存)。逻辑页面读取不像物理页面读取那样成问题,因为它们发生得更快,但它们仍然需要有限的时间。即使您拥有 1TB 的 RAM 并且整个数据库都缓存在内存中,处理器仍然需要有限的时间来搜索所有数据。如果 SQL Server 需要查看的数据较少,即使它完全缓存在 RAM 中,也总是更好的。

当您的数据无法装入 RAM 中且服务器必须从磁盘读取时,数据访问速度就会变慢。

就您的情况而言,SQL 似乎正在读取 20 GB 的数据。这超出了 6 GB 的数据缓存,因此 SQL Server 将通过从磁盘加载数据来覆盖它认为不再需要的“旧”数据,从而重新使用内存。如果 1 秒后出现另一个用户的另一个查询,SQL 可能必须返回磁盘重新读取该“旧”数据。

调整查询和改进索引应该会导致 SQL Server 需要查看的数据更少,这意味着必须查看的数据更有可能保留在数据缓存中、RAM 中,并且在所需数据不在数据缓存中的情况下,需要从磁盘读取的数据更少。

增加 RAM(“使用硬件解决问题”)也意味着将数据保存在 RAM 中的机会更大,但通常可以获得更大的改进(可能是 10 倍或更多,如果你很幸运并且索引一开始就很糟糕 - 我见过 60 倍甚至更好的改进),而不是通过增加可用于缓存数据的 RAM 数量(通常,如果没有新服务器或对 VM 环境施加未计划的大量压力,就不可能将 RAM 数量增加超过 2 倍或 3 倍。)当然,插入新的 RAM 芯片通常比调整查询更容易/更快,但有时您别无选择。

其他值得做的事是确保定期更新索引统计信息。在没有 DBA 的环境中,这种维护经常被忽略。过时的统计信息可能导致查询引擎使用低效的计划,这在大型表中尤其明显/痛苦。

最后一点:重新启动 SQL Server 将刷新所有缓存数据,并且在 SQL Server 重新启动后查询进入时必须从磁盘重新加载这些数据。通常,这意味着 SQL Server 在重新启动后会变得更慢,而不是更快。重新启动后速度更快的 SQL Server 通常经历了过多的阻塞(重新启动服务器会丢弃所有阻塞和被阻塞的连接),或者它们经历了查询风暴,导致它从磁盘读取大量数据(通常,这些查询是由心烦意乱的用户引起的,他们以几秒或几分钟的间隔重新提交相同的查询几次,因为事情“花费的时间太长”)。

相关内容