SQL Server单个查询内存使用情况

时间:2011-07-21 11:37:00

标签: sql sql-server sql-server-2008

我想找出或至少估计单个查询(特定查询)在执行时会占用多少内存。在此处发布查询没有意义,因为我想在多个查询上执行此操作,并查看是否对不同的数据库进行了更改。有没有办法获得这些信息?

使用SQL Server 2008 R2

感谢

吉拉德。

2 个答案:

答案 0 :(得分:6)

您可能需要查看DMV(动态管理视图),特别是sys.dm_exec_query_memory_grants。例如,请参阅此查询(取自here):

DECLARE @mgcounter INT
SET @mgcounter = 1
WHILE @mgcounter <= 5 -- return data from dmv 5 times when there is data
BEGIN
    IF (SELECT COUNT(*)
      FROM sys.dm_exec_query_memory_grants) > 0
    BEGIN
             SELECT *
             FROM sys.dm_exec_query_memory_grants mg
                         CROSS APPLY sys.dm_exec_sql_text(mg.sql_handle) -- shows query text
             -- WAITFOR DELAY '00:00:01' -- add a delay if you see the exact same query in results
             SET @mgcounter = @mgcounter + 1
    END
END

在发出上述查询时,它将等待某个查询运行并收集内存数据。因此,要使用它,只需运行上面的查询,然后运行您要监视的查询。

答案 1 :(得分:6)

“查询占用的内存量是多少?”是什么意思?以及为什么要确切知道?

我不认为SQL Server中的内存以您可能想象的方式运行 - SQL Server中的内存管理是一个令人难以置信的复杂主题 - 您可以轻松编写有关SQL Server内存管理的全书。我不能声称知道 很多关于SQL Server内存管理的内容,但我知道几乎没有任何有用的信息可以通过知道单个查询占用多少内存来推断。 / p>

那就是说,如果你确实想要了解在执行查询时发生的内存是什么,那么我可能会从查看缓冲池开始。 SQL Server中几乎所有内存都被组织成8KB块(与页面大小相同)的内存,可用于存储从数据页或索引页到缓存查询计划的任何内容。缓冲池是SQL Server中的主要内存组件 - 所有未在其他地方使用的8KB内存块仍保留在缓冲池中,以用作数据页的缓存。

请注意,为了使用数据页或索引页,它必须存在于内存中 - 这意味着如果它在其他地方的内存中尚未存在就可以使用,则必须提供一个空闲缓冲区以准备好页面到。缓冲池既可作为“可消耗”的可用缓冲池,也可作为内存中已存在的页面缓存。

您可以使用DMV检查缓冲池中的内容,此页面上列出了一个合适的查询:

使用命令DBCC DROPCLEANBUFFERS清除缓冲池(不要在生产SQL Server上执行此操作!!! )然后执行查询,理论上会出现新页面缓冲池中的页面应该是上次查询中使用的页面。

这可以让您大致了解查询中使用的数据和索引页面,但不包括使用内存的SQL Server的其他区域,例如查询计划缓存,SQL Server Workers等。

就像我说的,SQL Server内存管理很复杂 - 如果你真的想了解更多,我建议你在SQL Server内部购买一本书。

更新:您还可以使用查询统计信息查看查询的聚合性能统计信息,包括“物理读取”(从磁盘读取的页面)和“logcal读取”(从中读取的页面)缓冲池)。有关合适的查询,请参阅this page

这也可能会给你一些关于查询使用多少内存的提示,但要注意 - 在我周围发现的查询执行的逻辑读取比物理读取要多得多,据我所知,这意味着他们一遍又一遍地阅读相同的页面,即100个逻辑读取!=缓冲池中使用的100个页面。