我知道这个请求有点搞笑,但我想禁用我们开发数据库上的页面缓存。我相信这样可以更容易地看到所做的各种调整的影响,我最好奇的是检索未缓存页面的时间,而不是 MSSQL 从缓存中提取数据的效率。
但是,这必须在数据库级别完成,因此我不能仅将服务器的内存缓存设置为极低的级别(这有可能破坏索引缓存,而我宁愿不这样做,并且我们的开发系统还有其他我不想触碰的数据库)。
据我所知,刷新数据库的命令将会刷新所有数据库,但我不想对我们的开发数据库执行此操作。
这并不是什么强制性的要求,但是当我可以将整个开发数据库放入页面缓存中时,基准测试很难正确进行。
答案1
考虑在运行测试之前使用 DBCC DROPCLEANBUFFERS。这将按您的要求执行操作,一次性删除缓存。您需要在每次测试开始时运行它。
答案2
如果您的测试数据库未被其他任何程序使用,您可以分离然后立即重新连接数据库。(您可以使用几个系统存储过程调用 sp_detach_db 和 sp_attach_db 来执行此操作。)这会将所有页面从缓存中丢弃,并且在您开始运行查询之前,缓存的数据页面(如果有的话)将非常少。
当然,如果您正在对比单个查询更复杂的东西进行基准测试,而其他人在您的共享开发系统上对其他数据库运行大型查询,那么您的结果(以运行查询的秒数来衡量)可能会出现偏差,因为您的部分或全部页面可能会被丢弃出数据缓存,从而使您的查询运行时间比平时更长。
如果您的目标是对单个查询(或一组查询或一个存储过程)进行基准测试以期对其进行优化,而您没有自己的服务器,我建议您关注页面读取,而不是运行查询所需的时间。
如果您有一台慢速(开发)服务器和一台快速(生产)服务器,且数据和代码相同,则查询可能在慢速服务器上运行 10 秒,而在快速服务器上运行 1 秒。它们都将读取相同数量的页面。(您会发现一些细微的变化,但通常不超过 1%。)如果您改进查询,使其在慢速服务器上读取的页面更少,则它在快速服务器上读取的页面也会更少。读取页面较少的查询几乎总是性能最佳。
您可以从 Profiler 获取页面读取信息,它可以监视任何客户端程序。(使用 Profiler 时,请务必过滤掉您不需要的任何连接/数据库/事件/列,并确保不会影响您正在分析的服务器的性能。)
(当开发系统是单核而服务器可能是双核或四核时,这曾经更加困难。对于大查询,开发系统上的计划会有所不同,而大查询通常是您想要优化的。)
另一个角度是,在 SSMS 中运行查询时,观察查询的逻辑读取和物理读取。在查询选项对话框中查找“set statistics I/O on”选项。它位于“高级”部分下。这最适合单个查询或简单的存储过程。对于涉及很多表的复杂事物,情况会变得很糟糕。在这种情况下,尝试找到一些最严重的问题并隔离真正糟糕的部分,然后详细查看这些部分。
您需要尽量减少逻辑读取。如果您尽量减少逻辑读取,当服务器需要从磁盘提取数据时,物理读取也应该会减少。此外,在您需要的数据被缓存的情况下,尽量减少逻辑读取将使查询运行得更快。