SQL Server为啥使用了这么多内存?

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

今天微博上看到的,觉得很不错,立马转过来, 原文地址:http://support.microsoft.com/gp/anxin_techtip6/zh-cn

SQL Server的用户,常常会发现SQL进程使用了很多内存。这些内存大多数都是用来缓存用户要访问的数据,以达到最优的效率。那怎么能够知道哪些数据现在正缓存在内存中呢?其实,数据库管理员跑几句查询,就能得到答案。

谁占用了我的Buffer Pool?
我在做SQL Server 7.0技术支持的时候有客户问我,“我的SQL Server buffer pool很大,有办法知道是哪些对象吃掉我的buffer Pool内存么?比方说,能否知道是哪个数据库,哪个表,哪个index占用了buffer Pool么?”当时我没有找到这个问题的答案,但是我一直记着这个问题。直到SQL server 2005 版本出现,这个问题迎刃而解。答案就是使用动态视图(DMV) sys.dm_os_buffer_descriptors。这个DMV非常强大。根据SQL Server 联机丛书,这个视图的作用是 “返回有关 SQL Server 缓冲池中当前所有数据页的信息。可以使用该视图的输出,根据数据库、对象或类型来确定缓冲池内数据库页的分布”。具体点说,这个视图能够返回buffer pool里面一个8K 的data page的下列属性:
(1)该页属于哪个数据库
(2)该页属于数据库哪个文件
(3)该页的Page_ID
(4)该页的类型。可以根据这个来判断此页时索引页还是数据页
(5)该页内有多少行数据
(6)该页有多少可用空间。
(7)该页从磁盘读取以来是否修改过。
有了上面的信息,我们就可以很方便的统计出几种很有用的数据,如下。

 1. Buffer Pool的内存主要是由那个数据库占了?

SELECT count(*)*8  as cached_pages_kb,CASE database_id
        WHEN 32767 THEN 'ResourceDb'
        ELSE db_name(database_id)
        END AS Database_name
FROM sys.dm_os_buffer_descriptors
GROUP BY db_name(database_id) ,database_id
ORDER BY cached_pages_kb DESC;

结果如下:


从上面的结果可以看到数据库AdventureWorks占用了大概30MB左右的缓冲池空间。
注意该DMV 并不返回Buffer Pool里面有关非数据页(如执行计划的缓存等)的信息。也就是说这个DMV并没有返回Buffer Pool里面所有页面的信息。
    2. 再具体一点,当前数据库的哪个表或者索引占用Pool缓冲空间最多?


SELECT count(*)*8 AS cached_pages_kb
    ,obj.name ,obj.index_id,b.type_desc,b.name
FROM sys.dm_os_buffer_descriptors AS bd
    INNER JOIN
    (
        SELECT object_name(object_id) AS name
            ,index_id ,allocation_unit_id,object_id
        FROM sys.allocation_units AS au
            INNER JOIN sys.partitions AS p
                ON au.container_id = p.hobt_id
                    AND (au.type = 1 OR au.type = 3)
        UNION ALL
        SELECT object_name(object_id) AS name  
            ,index_id, allocation_unit_id,object_id
        FROM sys.allocation_units AS au
            INNER JOIN sys.partitions AS p
                ON au.container_id = p.partition_id
                    AND au.type = 2
    ) AS obj
        ON bd.allocation_unit_id = obj.allocation_unit_id
        LEFT JOIN sys.indexes b on b.object_id = obj.object_id AND b.index_id = obj.index_id
WHERE database_id = db_id()
GROUP BY obj.name, obj.index_id ,b.name,b.type_desc
ORDER BY cached_pages_kb DESC;

输出结果如下 (部分):


从上面的结果可以看到表Individual 在Pool内存里面缓冲最多,可能这个就是经常访问的热表,或者是比较大的表。注意Pool里面的缓冲页是经常变化的。 你如果再跑一次语句,出现在头条的可能是另外一个表了。
    3. Buffer Pool缓冲池里面修改过的页总数大小。这个比较容易:

SELECT count(*)*8  as cached_pages_kb,
       convert(varchar(5),convert(decimal(5,2),(100-1.0*(select count(*) from sys.dm_os_buffer_descriptors b where b.database_id=a.database_id and is_modified=0)/count(*)*100.0)))+'%' modified_percentage
        ,CASE database_id span>
        WHEN 32767 THEN 'ResourceDb'
        ELSE db_name(database_id)
        END AS Database_name
FROM sys.dm_os_buffer_descriptors a
GROUP BY db_name(database_id) ,database_id
ORDER BY cached_pages_kb DESC;

结果:

从上面的结果可以看到,AdventureWorks数据库大概有13.84%的数据是修改过的。如果一个数据库的大部分(超过80%) 是修改过的,那么这个数据库写操作非常多。反之如果这个比例接近0,那么该数据库的活动几乎是只读的。读写的比例对磁盘的安排是很重要的。当然还有其他性能数据来获得数据库读写的大概比例,这里限于篇幅就不多谈了。



监视SQL Server 内存使用 如果内存在等待超过 20 分钟后不可用,则 SQL Server 将终止查询,出现错误 8645“等待内存资源在资源池”default“中执行查询时出现超时。最初,查询会请求该执行内存,如果授予此内存,查询将使用内存的全部或部分内存来对结果或哈希存储桶进行排序。在查询执行期间分配的此内存称为内存授予。例如,如果查询执行对内存中非常大的行集执行排序操作,则排序可能需要几秒钟或几分钟时间,并且授予的内存用于查询的生存期。查询执行内存(QE 内存): 此术语用于突出显示在执行查询期间使用排序或哈希内存的事实。 阅读详情

相关推荐

InnoDBBufferPool管理调研_何登成

InnoDB Buffer Pool,可以说是 InnoDB 系统内部最重要的模块之一。通过系统参数 innodb_buffer_pool_size,用户可以设置几 G,几十 G,乃至上百 G 的内存空间。那么,InnoDB 系统是如何管理这么大一片内存空间的呢?

浅析在线调整 innodb_buffer_pool_size

浅析在线调整 innodb_buffer_pool_size 作者:zhou mysql版本:5.7 先介绍一下 buffer pool: 在innodb存储引擎中数据访问以page为单位,page也是innodb管理数据库的最小磁盘单位,每个page的默认大小为16KB(可以通过参数innodb_page_size进行调整,在5.7增加了对32KB和64KB的大小支持,在此之前的版本支持4KB,8KB,16KB的大小设定),而buffer_pool是用来管理和缓存这些page的,innodb会把一块连续的内存划分给buffer_pool使用,并把buffer_pool等分为buffer

SQL Server 2008 R2占用cpu、内存越来越大的两种解决方法

SQL Server 2008 R2运行越久,占用内存会越来越大。 第一种: 有了上边的分析结果,解决方法就简单了,定期重启下SQL Server 2008 R2数据库服务即可,使用任务计划定期执行下边批处理: net stop sqlserveragent net stop mssqlserver net start mssqlserver net start sqlserveragent 第二种: 进入Sql server 企业管理器(管理数据库和表的,这个都不知道就不用往下看了),在数据库服务器名称上点击【右键】,选择【属性】,然后,找到【内存】选项,在右边的【使用AWE分配内存】(s

谁占用了我的Buffer Pool?

我在做SQL Server 7.0技术支持的时候有客户问我,“我的SQL Server buffer pool很大,有办法知道是哪些对象吃掉我的buffer Pool内存么?比方说,能否知道是哪个数据库,哪个表,哪个index占用了buffer Pool么?”当时我没有找到这个问题的答案,但是我一直记着这个问题。直到SQL server 2005 版本出现,这个问题迎刃而解。答案就是使用动态视图(...

weixin_30764883的博客 152

MySQL存储引擎之InnoDB - 缓冲池(buffer pool)

1、前言 操作系统,会有缓冲池(buffer pool)机制,避免每次访问磁盘,以加速数据的访问。 应用系统分层架构,为了加速数据访问,会把最常访问的数据,放在缓存(cache)里,避免每次都去访问数据库。 MySQL作为一个存储系统,同样具有缓冲池(buffer pool)机制,以避免每次查询数据都进行磁盘IO。 2、初识缓冲池 InnoDB的缓冲池的缓存内容与作用 缓存表数据与索引数据,把磁盘上的数据加载到缓冲池,避免每次访问都进行磁盘IO,起到加速访问的作用。(速度快,那为啥不把所有数据

weixin_39997438的博客 982

史上最全的sqlserver运维分析工具,汇总都在这里了,适合sqlserver的dba人员

比较常用的sqlserver运维分析语句 SELECT TOP 2000 ST.text AS '执行的SQL语句', QS.execution_count AS '执行次数', QS.total_elapsed_time AS '耗时', QS.total_logical_reads AS '逻辑读取次数', QS.total_logical_writes AS '逻辑写入次数', QS.total_physic.

deriva的专栏 2001

从零开始深入了解MySQLBuffer Pool

- 这里我们要注意一点,Buffer Pool的描述数据大概相当于缓存页的5%左右,假设你设置的Buffer Pool的大小是128Mb,实际上可能会大一些,因为他里面还要存放信息描述数据。-- 所以当我们要更新一条数据,首先会找到这行数据所在的数据页,然后从磁盘文件里把这行数据所在的数据页直接加载到Buffer Pool中,如下图。

lt_xiaodou的博客 842

[转]SQL Server为啥使用了这么内存

原文地址:http://support.microsoft.com/gp/anxin_techtip6/zh-cn SQL Server为啥使用了这么内存SQL Server的用户,常常会发现SQL进程使用了很内存。这些内存数都是用来缓存用户要访问的数据,以达到最优的效率。那怎么能够知道哪些数据现在正缓存在内存中呢?其实,数据库管理员跑几句查询,就能得到答案。 谁占用了我的Buf...

weixin_30613343的博客 101

AI短片创作:用导演思维和提示词模板告别塑料感

随着人工智能生成内容技术的快速发展,AI视频生成工具让普通人也能创作短片。然而,许作品仍带有“AI塑料感”,根源在于缺乏导演思维。本文从提示词设计、镜头语言、光影控制和工作流搭建出发,系统讲解如何用可复用的模板拆解脚本、构图与运镜,并对人物一致性、动作自然度等常见问题进行排查。文章面向入门与进阶用户,强调“前期控制、后期补救”的工程化流程,帮助创作者稳定产出具有电影质感的AI短片。将抽象的视频生成概念落到可执行的实操方法,是提升AI短片质量的关键。

weixin_34221332的博客 423

优化SQL Server内存占用之执行缓存

首先说明一下SQL Server内存占用由哪几部分组成。SQL Server占用的内存主要由三部分组成:数据缓存(Data Buffer)、执行缓存(Procedure Cache)、以及SQL Server引擎程序。SQL Server引擎程序所占用缓存一般相对变化不大,则我们进行内存调优的主要着眼点在数据缓存和执行缓存的控制上。本文主要介绍一下执行缓存的调优。数据缓存的调优将在另外的文章中介绍。 对于减少执行缓存的占用,主要可以通过使用参数化查询减少内存占用。 1、使用参数化查询减少执行缓存占用 我们通过如下例子来说明一下使用参数化查询对缓存占用的影响。为方便试验,我们使用了一台没有其它负

SQL SERVER内存会不断增加

SQL SERVER内存会不断增加 这是由sql server内存管理机制决定的 当 SQL Server 数据库引擎在 Microsoft® Windows NT® 或 Windows® 2000 上运行时,其默认内存管理行为并不是获取特定的内存量,而是在不产生余换页 I/O 的情况下获取尽可能内存。为此,数据库引擎获取尽可能的可用内存,同时保留足够的可用内存

1557

MS SQL 内存使用异常

状况 : 操作系统的任务管理器中, MSSQL 一停用。内存使用状诚指示条一下就降到接近 0 当我一启动 MSSQL 服务,任务管理器中的内存使用状态指示条一上到 70% 左右,再仔细看任务管理器中 SQL 进程的内存使用大少才 70 M 70 兆确认没有看错 ) 而任务管理器中的可能最大内存是 3.6G . 重启服务器也是一样的状况 . 别外我 MSSQL 中有大约有建 10 个 DB. 问题:

h_leuyhhnnmoplppo的专栏 418

SQL Server中TOP子句可能导致的问题以及解决办法

简介      在SQL Server中,针对复杂查询使用TOP子句可能会出现对性能的影响,这种影响可能是好的影响,也可能是坏的影响,针对不同的情况有不同的可能性。      关系数据库SQL语句只是一个抽象的概念,不包含任何实现。很元数据都会影响执行计划的生成,SQL语句本身并不作为生成执行计划所参考的元数据(提示除外),但TOP关键字却是直接影响执行计划的一个关键字,因此在某些情况下使...

weixin_34361881的博客 182

SQL Server内存架构基础

翻译自: https://mssqlwiki.com/sqlwiki/sql-performance/basics-of-sql-server-memory-architecture/ 1.32位SQL Server内存架构 在Win32内存架构里,每个进程有4GB的虚拟地址空间。默认情况下,2GB的地址空间可从用户模式访问(应用程序...

weixin_33851177的博客 267
上一篇: SQL Server DTS/SSIS 滥用之复制数据库对象
下一篇: 配置SQL Server服务帐户特权
billpu
博客等级 码龄22年 95粉丝 3原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值