1、内存使用分类

按用途分类
1)Database cache(数据页面)。SQL Server中的页面都是以8KB为一个页面存储的。当SQL Server需要用到某个页面时,它会将该页面读到内存中,使用完后会缓存在内存中。在内存没有压力的情况下,SQL Server不会将页面从内存中删除。如果SQL Server感觉到内存的压力时,会将最长时间没有使用的页面从内存中删除来空出内存。
2)各类Consumer(功能组件)
Connection的连接信息
General:一组大杂烩。语句的编译、范式化、每个锁数据结构、事务上下文、表格和索引的元数据等
Query Plan:语句和存储过程的执行计划。和Database cache类似,SQL Server也会将执行计划缓存以供将来使用,减少编译时间。
Optimizer:生成执行计划的过程中消耗的内存。
Utilities:像BCP、Log Manager、Backup等比较特殊的操作消耗的内存。
3)线程内存:存放进程内每个线程的数据结构和相关信息消耗的内存,每个线程需0.5MB的内存。
4)第三方代码消耗的内存:SQL Server的进程里,会运行一些非SQL Server自身的代码。例如:用户定义的CLR或Extended Stored PRocedure代码。
按申请方式分类
1)预先Reserve一块大的内存,然后在使用的时候一块一块的Commit。Database Page是按这种方式申请的。
2)直接用Commit方式申请的内存,成为Stolen方式。除了Database Page之外其他内存基本都是按这种方式申请的。
按申请内存的大小分类
1)申请小于等于8KB为一个单位的内存,这些内存称为Buffer Pool

2)申请大于8KB为一个单位的内存,这些内存称为Multi-Page(或MemToLeave)

SQL Server对于Database cache都是采用先Reserved后Commit的方式申请的,而数据页都是以8KB为单位进行申请的。
对于Consumer中的内存申请,一般都是按Stolen方式申请的,且大多数的执行计划的大小都是小于8KB的,少数特别复杂的存储过程的执行计划会超过8KB,默认的连接的数据包是4KB,除非客户端特别设置了超过8KB(不建议)
第三方代码的内存申请一般是按Stolen方式申请的,个别比如CLR中可能会用Reserved/Commit的方式申请。
线程的内存每个都以0.5MB的方式申请,自然是放在MemToLeave中。
之所以花了这么大篇幅来讲SQL Server的内存分类,是因为SQL Server尤其是32位的SQL Server对不同种类的内存的申请大小是不一样的,对Commit、Stolen和MemTOLeave等类型的内存是有限制的。因此会出现系统中还有空闲内存,但是SQL Server不会申请使用的现象。
2、SQL Server内存使用情况的分析
一般来说有两种方式,第一种就是用来分析系统内存情况时使用的用性能计数器来分析,第二种是使用动态管理视图(DMV,只适用于SQL Server2005和2008)
1)SQL Server性能计数器
SQLServer:Memory Manager:Total Server Memory(KB):SQL Server缓冲区提交的内存。不是SQL Server总的使用内存,只是Buffer Pool中的大小。
SQLServer:Memory Manager:Target Server Memory(KB):服务器可供SQL Server使用的内存量。一般是由SQL Server能访问到的内存量和SQL Server的sp_Configure配置中的Max Server Memory值中的较小值算得。
SQLServer:Memory Manger:Memory Grants Pending:等待内存授权的进程总数。如果该值不为0,说明当前有用户的内存申请由于内存压力被延迟,这意味着比较严重的内存瓶颈。
SQLServer:Buffer Manager:Buffer Cache Hit Ratio:数据从缓冲区中找到而不需要从硬盘中去取的百分比。SQL Server在运行一段时间后,该比率的变化应该很小,而且都应该在98%以上,如果在95%以下,说明有内存不足的问题。
SQLServer:Buffer Manager:Lazy Writes/Sec:每秒钟被惰性编辑器(Lazy writer)写入的缓冲数。当SQL Server感觉到内存压力的时候,会将最久没有使用的数据页面和执行计划从缓冲池中清理掉,做这个动作的就是Lazy Writer。
SQLServer:Buffer Manager:Page Life Expectancy:页面不被引用后,在缓冲池中停留的秒数。在内存没有压力的情况下,页面会一直待在缓冲池中,Page Life Expectancy会维持在一个比较高的值,如果有内存压力时,Page Life Expectancy会下降。所以如果Page Life Expectancy不能维持在一个值上,就代表SQLServer有内存瓶颈。
SQLServer:Buffer Manager:Database Pages :就是Database Cache的大小。
SQLServer:Buffer Manager:Free Pages:SQL Server中空闲可用的大小。
SQLServer:Buffer Manager:Stolen Pages:Buffer Pool中Stolen的大小。
SQLServer:Buffer Manager:Total Pages: Buffer Pool的总大小(等于Database Pages+Free Pages+Stolen Pages)。该值乘以8KB,应该等于Memory Manager:Total Server Memory的值。
从上面这些计数器中我们就能了解SQL Server的内存使用情况,结合前面说的系统层的计数器大概能看出是否存在内存瓶颈。
2)内存动态管理视图
在SQL Server 2005以后,SQL Server的内存管理是使用Memory Clerk的方式统一管理。所有的SQL Server的内存的申请或释放,都需要通过它们的Clerk,SQL Server也通过这些Clerk的协调来满足不同需求。通过查询这些DMV,可以得到比用性能计数器更加详细的内存使用情况。
我们可以通过下面的查询语句来检测SQL Server的Clerk的内存使用情况。
使用sys.dm_os_memory_clerks查看内存使用情况
SELECT type, --Clerk的类型
sum(virtual_memory_reserved_kb) as vm_Reserved_kb, -- 保留的内存
sum(virtual_memory_committed_kb) as vm_Committed_kb, --提交的内存
sum(awe_allocated_kb) as awe_Allocated_kb, -- 开启AWE后使用的内存
sum(shared_memory_reserved_kb) as sm_Reserved_kb, -- 共享的保留内存
sum(shared_memory_committed_kb) as sm_Committed_kb, -- 共享的提交内存
sum(single_pages_kb) as SinlgePage_kb, --Buffer Pool中的Stolen的内存
sum(multi_pages_kb) as Multipage_kb -- MemToLeave的内存
FROM sys.dm_os_memory_clerks
GROUP BY type
ORDER BY type
从上面的查询语句,我们可以算出前面提到的内存大小
Reserved/Commit = sum(virtual_memory_reserved_kb) / sum(virtual_memory_committed_kb)
Stolen = sum(single_pages_kb) + sum(multi_pages_kb)
Buffer Pool = sum(virtual_memory_committed_kb) + sum(single_pages_kb)
MemToLeave = sum(multi_pages_kb)
通过上面的介绍我们可以知道SQL Server总体和各部分内存的使用情况,如果我想知道数据页的缓存中到底缓存了哪些数据,这些数据是属于哪个数据库的哪个表中的呢?执行计划又是缓存了哪些语句的执行计划呢?这也可以通过DMV查看的到。
查看内存中的数据页面缓存的是哪个数据库的哪个表格的数据
declare @name nvarchar(100)
declare @cmd nvarchar(1000)
declare dbnames cursor for
select name from master.dbo.sysdatabases
open dbnames
fetch next from dbnames into @name
while @@fetch_status = 0
begin
set @cmd = 'select b.database_id, db=db_name(b.database_id),p.object_id,p.index_id,buffer_count=count(*) from '
--这里的object_id代表是SQL Server中的对象号,index_id代表是索引号,buffer_count代表的是页面数
+ @name + '.sys.allocation_units a, '
+ @name + '.sys.dm_os_buffer_descriptors b, ' + @name + '.sys.partitions p
where a.allocation_unit_id = b.allocation_unit_id
and a.container_id = p.hobt_id
and b.database_id = db_id(''' + @name + ''')
group by b.database_id,p.object_id, p.index_id
order by b.database_id, buffer_count desc'
exec (@cmd)
fetch next from dbnames into @name
end
close dbnames
deallocate dbnames
go
-- 根据上面取出来的@object_id找出是哪个数据库的哪个表
SELECT s.name AS table_schema, o.name as table_name --使用的就是table_schema.table_name表
FROM sys.sysobjects AS o INNER JOIN
sys.schemas AS s ON o.uid = s.schema_id
WHERE (o.id = @object_id)
-- 根据上面取出来的@object_id和@index_id找出索引的名称
SELECT id, indid, name as index_name -- index_name就是索引的名称
FROM sys.sysindexes
WHERE (id = @object_id) AND (indid = @index_id)
-- 根据上面取出来的表名table_schema.table_name和索引的名称index_name,还可以找出该索引是建立在哪些字段上的
EXEC sp_helpindex 'table_schema.table_name'
查看内存中缓存的执行计划,以及执行计划对应的语句:
-- 输出可能较大,请小心使用
SELECT usecounts, refcounts, size_in_bytes, cacheobjtype, objtype, text
FROM sys.dm_exec_cached_plans cp CROSS APPLY sys.dm_exec_sql_text(plan_handle)
ORDER BY objtype DESC

转载于:https://www.cnblogs.com/hnyei/archive/2011/09/29/2195891.html

SQL Server内部的内存管理相关推荐

  1. 深入SQL SERVER 2000的内存管理机制

    http://www.cnblogs.com/softj/articles/243591.html 转载于:https://www.cnblogs.com/zengkefu/p/6713169.htm ...

  2. SQL Server资源管理之内存管理篇(上)

    对SQL Server来说,最重要的资源是内存.Disk和CPU,其中内存又是重中之重,因为SQL Server为了性能要求,会将它所要访问的数据全部(只要内存足够)放到缓存中.这篇就来介绍SQL S ...

  3. 浅谈SQL Server内部运行机制

    原文:浅谈SQL Server内部运行机制 对于已经很熟悉T-SQL的读者,或者对于较专业的DBA来说,逻辑的增删改查,或者较复杂的SQL语句,都是非常简单的,不存在任何挑战,不值得一提,那么,SQL ...

  4. sql 缓冲池_监视SQL Server中的内存文员和缓冲池分配

    sql 缓冲池 The following article applies to SQL Server versions 2008 + 以下文章适用于SQL Server 2008 +版本 Adequ ...

  5. SQL Server占用服务器内存过高

    SQL Server对服务器内存的使用策略是用多少内存就占用多少内存,只用在服务器内存不足时,才会释放一点占用的内存,所以SQL Server 服务器内存往往会占用很高. 查看内存状态: DBCC M ...

  6. 为 SQL Server 启用 AWE 内存。

    今天突然想仔细了解下下AWE,所以微软的网站上查了查,顺便把查到的内容放到这里,嘿嘿嘿. 地址窗口化扩展插件 (AWE) 可以使 32 位操作系统访问大量内存.AWE 由操作系统提供,并且在 Micr ...

  7. C#毕业设计——基于C#+asp.net+SQL Server的服装连锁店管理系统设计与实现(毕业论文+程序源码)——服装连锁店管理系统

    基于C#+asp.net+SQL Server的服装连锁店管理系统设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于C#+asp.net+SQL Server的服装连锁店管理系统设计与实现, ...

  8. SQL SERVER占用服务器内存过高的解决方案

    SQL SERVER占用服务器内存过高的解决方案 参考文章: (1)SQL SERVER占用服务器内存过高的解决方案 (2)https://www.cnblogs.com/purple5252/p/1 ...

  9. SQL Server 扩展秘钥管理(EKM)

    无论是SQL Server 对称秘钥.非对称秘钥管理,还是使用对称秘钥或非对称秘钥对数据进行加密解密,以及数据库TDE,我们都有提到EKM(Extensible Key Manager),那么什么是E ...

  10. SQL Server性能优化与管理的艺术 附件下载地址

    首先感谢读者们对鄙人的支持,购买了<SQL Server性能优化与管理的艺术>,由于之前出版社的一些疏忽,附件没有上传成功,再次本人深表歉意. 请需要下载附件的读者从下面链接下载,谢谢: ...

最新文章

  1. linux之x86裁剪移植---字符界面sdl开发入门
  2. 学好python需要多久-python入门要学多久
  3. 解题报告 『[NOI2014]起床困难综合症(位运算)』
  4. Linux笔记 1-8 --文件传输
  5. 微信昵称可以加特效啦!
  6. 海思平台35xx系列sensor不出图问题排查方法(新手来看)
  7. linux+极点五笔输入法,Linux技巧之Ubuntu11.04下安装极点五笔输入法
  8. Pycharm 编辑器取消中间分割线
  9. HC Bridge容器网络模式分享
  10. html在搜索按钮中加放大镜,点击放大镜搜索图标
  11. jenkins调查总结
  12. 这10个超厉害的工具堪称神器,却很少人知道!
  13. Python判断素数(质数)——循换结构、控制及else循环扩展模式的实践
  14. 中国石油大学(北京)-《 完井工程》第三阶段在线作业
  15. Mac ps 2021 3D功能无法使用问题,怎么办?
  16. LiteOS学习(一)任务
  17. 平头哥面试——数字IC1
  18. 西北工业大学 计算机学院 姜,姜学锋(计算机学院)老师 - 西北工业大学 - 院校大全...
  19. 那些你不知道的TCP冷门知识!
  20. windows 搭建代理服务器 - Fiddler

热门文章

  1. 变量的命名规则与惯例
  2. PHP常量详解:define和const的区别
  3. spring boot 2.0 与FASTDFS进行整合
  4. SpringContext扩展BeanFactory
  5. C++的三种交换数值的方式(值传递、地址传递、引用传递)
  6. shell脚本基础练习题
  7. fullPage最后一屏自适应
  8. python中-----数组中的排序
  9. 修改UINavigationController返回按钮的标题及如何隐藏导航栏
  10. php session 设置无效