查询性能随着时间和使用而下降

use*_*436 7 performance index sql-server-2005

几个星期以来,我一直在解决一个问题,我的 SQL Server 查询的性能在使用几天后会下降。此外,每隔几天,我的应用程序的 ODBCSQLExecute()调用就不会返回查询。

手动重建索引(在 SQL Server Management Studio 中)“修复”了这两个问题。

这是更多信息;

  • DB 大小约为 13 Gig
  • 在应用程序中使用 ODBC 版本 3.5.1
  • 这些应用程序是 C++,带有到 SQL DB 的 ODBC 接口
  • 测试用例在静态数据库上 - 没有插入,因此应该不可能有碎片!
  • 小查询最初不到 1 秒,然后降级到 50 秒以上
  • 在它运行的所有 (3) 台机器上都看到了这个问题

我很难理解为什么相同的查询在一段时间内可以正常工作,但随后开始减慢 waaay ?

任何想法将不胜感激。

Mik*_*lsh 10

由于一些原因,查询可能会随着时间的推移开始变慢,而您重建索引可以通过几种方式解决问题。在我的经验中,我将分享一些更常见的原因,但也可能有其他原因。我的猜测是您遇到了这些问题之一。我还提出了一些问题作为对您问题的评论,以查看我们是否可以获得更多详细信息。但是有几点想法:

统计信息 获取陈旧SQL Server 维护列和索引统计信息。这些本质上告诉查询优化器您的数据是如何分布的。此信息对于优化器选择正确的数据访问方法(Seek 与 Scan)然后选择正在使用的连接方法至关重要。如果您启用了自动更新统计信息(SQL 中的默认设置。在数据库级别),这些会被重新计算,但仅当“足够”的数据发生变化时。因此,如果您在表中插入了一些数据,但从未手动更新统计数据,并且插入/更新不足以触发自动统计数据更新,那么您的数据分发计划可能会很糟糕……重建索引也会重新计算索引统计数据 我会创建一个作业来定期手动更新统计信息,无论如何这是最佳实践 - 下次发生这种情况时,请尝试sp_updatestats在您的数据库中运行,看看您是否注意到不同

查询计划问题您可能会遇到参数嗅探——基本上是第一次查询运行时传入一个值——查询会针对该值进行优化。当您下次使用可以受益于不同查询计划的不同值运行它时,它会受到原始查询计划的影响,从而导致查询速度变慢。当应用程序运行缓慢时 - 如果您在 SQL Server Management Studio 中运行相同的查询,它们是否也会变慢?如果它在 SSMS 中很快,但在应用程序中很慢 - 这可能是指向参数嗅探的好兆头。如果随着时间的推移,无论参数如何,所有查询的速度都一直很慢,那么我不会看这里。这篇文章谈了很多关于参数嗅探的内容。

内存不足/临时计划太多听起来您正在向 SQL Server 发送临时 SQL。这有时会使您的计划缓存膨胀,特别是如果您为每次查询执行都有一个单独的计划。根据服务器上的内存,这也可能导致问题。你的服务器有多少内存?查看有关一次性使用计划问题的链接。在 SQL Server 2005 中没有很多很好的解决方案来解决这个问题,如果你有的话。如果您可以在非生产环境中重现此问题,DBCC FREEPROCCACHE如果再次发生这种情况,我建议您在非生产环境中运行。 请注意!这是一个实例范围的设置,如果您在生产中执行此操作 - 任何数据库缓存中存储的任何查询计划将不再存在。这意味着您必须再次为编辑“付费”。如果您有高并发性和繁忙的系统,这可能会导致问题。如果这是唯一真正的数据库,并正在从性能问题反正痛苦,它不会伤害尝试这种在生产..如果您有其他数据库,只想做这个数据库,这篇博客文章介绍了如何方法只有一个 DB 的清除。

索引碎片-索引碎片可能是这里的实际问题,但我很惊讶它这么快变得如此糟糕。如果您的表聚集在一个导致碎片迅速的键上并且您有很多插入,则可能是这种情况。如果您在内存和磁盘 IO 方面动力不足,情况会变得更糟。设置一项定期重建/重组索引的工作会很好。根据您对上述评论中某些问题的回答,可能还需要采取其他措施来最大程度地减少这种影响。


Joh*_* N. 5

我们的生产数据库之一也遇到了同样的问题。然而情况略有不同。这些表是读/写和包含大约。20+ 百万条记录。

我们每周(周末)重建索引,这有助于直到周一下午,然后由于数据量巨大,性能会下降。

根据您的表的大小,它可能是内存问题,其中服务器只有一定数量的空间可用于缓存中的一定数量的记录集。(缓冲区缓存命中率低于 90%)。解决方案:向 SQL Server 实例添加更多内存可能会有所帮助。这可能会将缓冲区缓存命中率提高到 90% 以上。结果是从内存而不是从物理驱动器中检索数据。

如果是因为 SQL 数据库引擎正在“优化”旨在检索数据的查询,则可能是索引统计问题。(这是我们大桌子的问题)。统计数据已经过时了。解决方案:每天刷新此表的索引统计信息可能会解决您的问题。

看到您的问题是一个短期问题,我猜这是一个缓冲区缓存命中率(SQL 内存太少)问题。SQL 查询优化器将从内存中删除小记录集以容纳更频繁检索的数据。


小智 1

我想到了一些事情。

  1. ODBC 连接对象是否在每个查询结束时关闭并删除?否则连接池将继续增长。

  2. 是否有缺失的索引?动态管理视图将告诉您那里发生了什么。