为什么查询导致溢出到tempdb?


27

背景

我正在将160gb数据库从具有48gb RAM的Win 2008服务器上的MSSQL 2008(标准)迁移到具有64gb RAM的Win 2012上运行MSSQL 2012(64位网络版)的新服务器上。旧服务器处于活动状态并处于负载状态;新服务器未投入生产。新服务器具有8个tempdb文件(每个4GB)。

问题

在新服务器上进行测试时,我看到许多查询中的步骤引起警报,提示“操作员在执行过程中使用tempdb溢出数据”。我已经能够通过重写一些查询来避免排序,但这并不能真正解决问题。旧服务器上的相同查询不会引起溢出。我读过,当MSSQL无法完成内存中的操作并不得不溢出/分页到tempdb中时,就会发生溢出。我应该担心泄漏吗?

例子

在此处输入图片说明

我已经在数据库上运行了sp_updatestats,因此统计信息应该是最新的,但是您会注意到估计的行数与实际的行数之间存在一些差异。

内存问题

我已为64GB的MSSQL设置了最大内存设置。当前,MSSQL已消耗了大约35gb的内存,但是工作集只有682mb。旧服务器(尽管在生产中,正在处理负载)具有44gb的内存分配给MSSQL,其中43.5gb在其工作集中。

在此处输入图片说明

我不知道泄漏是否与记忆设置有关-任何人有任何想法吗?MSSQL当前有英亩的可用内存,那么为什么它会因某种排序和散列匹配而溢出到tempdb中?


7
执行计划中的警报是2012年的新警报。您是否检查过警报是否一直在旧服务器上溢出?您是否为此监视?
Martin Smith

@MartinSmith啊,没有意识到警报是新的。我没有监视旧服务器上的溢出。将对此进行调查。

1
略有切点,但我坐在10个表联接的前面,默认情况下,该联接大多数情况下使用合并联接,并且行估计非常好,这会导致tempdb 0级溢出和运行时25s。强制哈希联接(和顺序)可消除溢出并在9s内运行。我只想知道它是合并还是散列还是溢出会引起差异,以及优化器是否正确地权衡了看似即将到来的溢出的影响(因为行估计非常好)。
crokusek

新服务器有硬件numa吗?
stacylaray

Answers:


28

这里有几个不同的问题:

问:为什么查询以前没有溢出?

它们确实是,但是SQL Server Management Studio并没有在SQL 2012之前将其作为明显的错误浮出水面。这是一个很好的示例,说明了为什么在进行性能调整时,您必须比图形执行计划更深入。

问:为什么查询会溢出到磁盘?

因为SQL Server没有授予他们足够的内存来完成其操作。执行计划可能低估了所需的内存量,或者存储盒承受了内存压力,或者它们只是大查询。(请记住,SQL Server将内存用于三件事-缓存原始数据页,缓存执行计划以及用于查询的工作空间。该工作空间的内存最终很小。)

问:如何减少泄漏?

通过编写可修改的T-SQL语句,具有最新的统计信息,在服务器中放置足够的内存,构建正确的索引以及在事情无法按您预期的方式工作时解释执行计划。查看Grant Fritchey的书《 SQL Server查询性能调优》,以获取所有这些内容的详细说明。

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.