Expert 诊断优化系列------------------内存不够用么?

本文涉及的产品
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
云数据库 RDS SQL Server,基础系列 2核4GB
简介:

现在很多用户被数据库的慢的问题所困扰,又苦于花钱请一个专业的DBA成本太高。软件维护人员对数据库的了解又不是那么深入,所以导致问题迟迟不能解决,或只能暂时解决不能得到根治。开发人员解决数据问题基本又是搜遍百度各种方法尝试个遍,可能错过诊断问题的最佳时机又可能尝试一堆方法最后无奈放弃。

    怎么样让琐事缠身的程序维护人员,用最快的方式解决数据库出现的问题?怎么让我们程序员的痛苦降低到最小...每天喝喝茶水,看看新闻平安度过一天呢?本系列重要通过Expert for sqlserver 工具讲解下数据库遇到的各种问题的表象及导致这样问题的根本原因,让定位问题更准确,解决问题思路更清晰!!

    数据库的性能好坏,对于最终用户来说表现为点击的操作是否能够快速响应,那么反应到数据库上就是语句执行时间是否够短!

    对用运维人员数据库性能的表现,简单可能看成CPU 、内存、磁盘三巨头指标是否正常,上一篇讲述了CPU的基本诊断

Expert 诊断优化系列------------------你的CPU高么?

    本篇我们就从内存下手,看看内存能够看出哪些问题!

废话不多说,直接开整-----------------------------------------------------------------------------------------

    首先说明一个误区,你是否被这样的画面所震惊?

    

 

    我的服务器内存满了,就是这个导致我数据库慢!我的程序报错也是因为这个,什么都因为内存满了!!  赶紧加内存吧~ 

    这个答案是大写的 “不一定”,SQL SERVER是一个很爱内存的家伙,他会缓存你的数据,执行计划,连接信息等等,所以出现这个现象是很正常的,不要轻易下结论,除非你经过仔细的研究和分析!

    那么怎么去分析到底是不是内存不足导致的问题呢?  下面我们来说说!

主要用到的性能计数器(不知道什么是性能计数器的,请自行百度)

  1. Page life expectancy (数据库计数器:主要显示不被使用的页,将在缓存中停留的秒数 )
  2. Lazy writes/sec  (数据库计数器:惰性写入器会在内存有压力且有新的内存需求时触发,成批的刷新“老化的缓冲区”)
  3. Page Reads/sec,Page Writes/sec  (这里使用数据库级别计数器:当需要读取或写入的页不在内存中,需要到磁盘中读取时计数)
  4. Target Server Memory (KB)  (SQL server能够使用的内存总量)
  5. Total Server Memory (KB)  (SQL SERVER使用的内存总量,这里指BUFFER POOL的大小)
  6. Available MBytes  (系统系数器:主要显示系统还有多少可用内存)

  注:Target Server Memory (KB) - Total Server Memory (KB) 约等于SQL SERVER还可以使用的内存数。

 

  Available MBytes 主要显示系统中还多少空闲内存 (如果这个值较大,而SQL SERVER还可以使用的内存数为0或者较小,可以适当的调大max server memory(最大内存,稍后介绍))

    

   这里不再细说这三个计数器,我们主要通过前三个计数的联动来判断系统的内存是否真的存在压力!!!

   首先介绍一下,这三个计数器是如何联动的?

   概念出发:Page life expectancy 不被使用的页在缓存中停留的秒数,如果低说明内存压力

        Page Reads/sec 所要读的数据不在内存中需要物理读取

        Lazy writes/sec 内存压力时成批的刷新老化缓冲区 

   当一个操作需要大量读取数据,且数据页不在缓存中 ——》 那么需要大量从磁盘读取冷数据放入缓存(Page Reads/sec 升高) ——》缓存有明显压力的时候Lazy writes/sec就会触发(Lazy writes/sec升高),大批量的将老化的数据或缓存计划等刷出缓存 ——》数据被清出缓存,那么页生命周期就会下降(Page life expectancy)

    

    Page Reads/sec

    

    Lazy writes/sec

    

    Page life expectancy

    

 

 

    高能预警:当你看到自己的计数器是这个样子的时候,你给的出结论不应该单单是,我内存有压力!

    这个例子不光为了说明三计数器是联动,而且也可以看出规律,那就是每三小时一次明显的内存压力。正如第一篇CPU文章的介绍,这种规律性的表象,作为系统的维护人员,一定要仔细想想什么操作导致的问题?不要因为一个简单的配置问题而拖慢了整个系统!

    我通过对问题时间点的语句分析发现,这个系统每三小时进行一次日志备份,正常的日志备份不会导致这样的现象,但如果在日志备份的时候加上CHECKDB呢?

    这就是所说的不要因为一个小的失误而影响整个系统!

 

--------------------------------------------------------------------------------------------

系统内存不足的表象          

    下面展示一个内存压力的服务器这三个计数器的表象:

    Page Reads/sec

    

    Lazy writes/sec    

    

    Page life expectancy 页生命周期

    

 

     

    这几个计数器反应出的问题绝对是系统内存严重不足,计数器双高一低。那么当我们知道系统内存不足的时候应该怎么办呢?加内存么?

    不要急,下面我们说说如何让你的系统节省内存,也许做过这一轮优化,你的系统内存就够用了! 你没听错,就是-----优化!

 

优化-----让你的内存无压力

 

    你要给你的系统设置最大内存max server memory   

    

 

 

    问:我系统内存本来就不够为什么还要设置使用上限?我这服务器就给数据库用还用设置?

   答:数据库是运行在windows 上的应用,他和notepad对于操作系统来说本质上没区别,那么这就好比君(操作系统)与 臣(数据库)的关系。

    而SQL SERVER是一个很喜欢内存的应用,所以很可能吃掉大量内存导致windows系统没有足够内存使用,,那么这时候君臣关系就体现的淋漓尽致了,君(windows) 要臣(SQL SERVER)死(释放内存)臣不得不死呀...这个释放在一定程度上可不是单单让windows够用了,很可能导致SQL内存陡降,以致SQL 短时间假死(操作无响应)。所以为了你数据库的稳定性,这个最大上限一定要设置。

 

    内存设置推荐:

    一般我比较推荐如果内存较小操作系统预留3G-4G ,如果内存大256或512以上在数据库内存无压力时预留5%给操作系统,剩下给SQL SERVER ,如果服务器还有其他应用还要在SQL 中减掉应用所占的内存。

    如果内存比较小且数据库内存压力大,则可以通过前面讲述的Available MBytes 的判断结果适量给系统预留内存。

 

    

    注意:最大内存的设置单位为 MB

 

语句的优化,让语句消耗内存更少!

    语句优化系列请关注后续文章,这里只针对降低内存

    降低内存对语句优化主要集中在几个方面:

  1. 是否缺失索引? 
  2. 消耗内存的操作是否可以消除(如排序)
  3. 降低语句复杂性,让优化器能选用最佳计划

 

    语句消耗内存主要体现在大量的读取,或者有排序等操作。限于篇幅这里只做简单的例子,详细的语句优化请关注后续文章。

    所谓的读,写简单理解就是在语句执行时所需要用到的数据页数,需要的越多就需要越大的内存来缓存这些数据页。如果需要的页不在内存中还需要从磁盘读取 (磁盘读取就是为什么Page Reads/sec 会高)

    

 

    简单的一个加索引降低逻辑读的例子~

    

 

    

    

    语句使用了一个整个表扫描的计划,执行了 19秒,逻辑读取143800次,预读137236 (磁盘上读取),消耗了40KB 的内存 ,并且明确提示出缺少索引!

    那么我们加上提示缺少的索引,再次执行

    

    

 

    加上索引的语句执行不到1秒 逻辑读降低到13次,内存消耗已经可以忽略不计。这就是索引对语句的重要性!单条语句如此,你的系统中到底有多少这样的语句呢?

    

 

 

    再来看一个写法修改的例子 :

    

    

    

 

 

    只是简单的改了下语句的写法时间有7秒变成1秒,内存消耗从300+MB 变成 1MB

    

    这两个例子,告诉我们也许系统中简简单单做一些调整,内存的压力就会明显降低或者变得非常充足,所以在你下了一个需要购买内存的决定前,是否针对系统的语句进行过调优?

      

-----------------------------------------------------------------------------------------------------

 

 对于内存性能计数器的阀值简单说明

 

 Page life expectancy 计数器这个时间要高于多少才算正常呢?

    答:很多资料上多这个值都有误解,说是300S,300S是在十多年前的一个参考值,是基于当时的服务器内存受到4GB内存的限制的影响得到的,

  目前服务器内存动辄超过100GB的情况下,用同样的标准,显然是不够准确的,这个值的计算是跟具体的服务器内存配置有关的,一个可供参考的标准算法是 Max Buffer Pool(GB)/4*300(S)

 

 

 

为什么这里缺少了一个 Buffer Cache hit ratio 计数器?

很多材料上都介绍其阈值是90%,95%之类的参考值,其实都是错误的,

    其实真正观察过的人,早就会发现,从PLE和Buffer hit ratio得出根本不一致的结论。

 

详细说明请参见:wy123的博客

Sql Server 内存相关计数器以及内存压力诊断

Buffer cache hit ratio性能计数器真的可以作为内存瓶颈的判断指标吗?

 

 

 

 -----------------------------------------------------------------------------------------------------

  总结:内存对于数据库来说是最为重要的依赖之一,内存的问题诊断和优化对系统至关重要。

     优化语句可以让你的系统内存压力明显降低。

     语句优化所带来的效果,在很大程度上会比添加硬件更有效!

     作为一个技术人员对于系统问题的定位、分析、调优是最重要的,如果内存问题都通过加内存来解决,我们的价值何在呢?

 

 

 

 ----------------------------------------------------------------------------------------------------

注:此文章为原创,欢迎转载,请在文章页面明显位置给出此文链接!
若您觉得这篇文章还不错请点击下右下角的推荐,非常感谢!

  引用高大侠的一句话 :“拒绝SQL Server背锅,从我做起!”

为了方便阅读给出系列文章的导读链接:

SQL SERVER全面优化-------Expert for SQL Server 诊断系列

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情: https://www.aliyun.com/product/rds/sqlserver
目录
相关文章
|
1月前
|
存储 缓存 监控
|
9天前
|
缓存 算法 Java
本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制
在现代软件开发中,性能优化至关重要。本文聚焦于Java内存管理与调优,介绍Java内存模型、内存泄漏检测与预防、高效字符串拼接、数据结构优化及垃圾回收机制。通过调整垃圾回收器参数、优化堆大小与布局、使用对象池和缓存技术,开发者可显著提升应用性能和稳定性。
30 6
|
9天前
|
监控 安全 程序员
如何使用内存池池来优化应用程序性能
如何使用内存池池来优化应用程序性能
|
9天前
|
存储 监控 Java
深入理解计算机内存管理:优化策略与实践
深入理解计算机内存管理:优化策略与实践
|
21天前
|
存储 JavaScript 前端开发
如何优化代码以避免闭包引起的内存泄露
本文介绍了闭包引起内存泄露的原因,并提供了几种优化代码的策略,帮助开发者有效避免内存泄露问题,提升应用性能。
|
22天前
|
并行计算 算法 IDE
【灵码助力Cuda算法分析】分析共享内存的矩阵乘法优化
本文介绍了如何利用通义灵码在Visual Studio 2022中对基于CUDA的共享内存矩阵乘法优化代码进行深入分析。文章从整体程序结构入手,逐步深入到线程调度、矩阵分块、循环展开等关键细节,最后通过带入具体值的方式进一步解析复杂循环逻辑,展示了通义灵码在辅助理解和优化CUDA编程中的强大功能。
|
1月前
|
存储 弹性计算 算法
前端大模型应用笔记(四):如何在资源受限例如1核和1G内存的端侧或ECS上运行一个合适的向量存储库及如何优化
本文探讨了在资源受限的嵌入式设备(如1核处理器和1GB内存)上实现高效向量存储和检索的方法,旨在支持端侧大模型应用。文章分析了Annoy、HNSWLib、NMSLib、FLANN、VP-Trees和Lshbox等向量存储库的特点与适用场景,推荐Annoy作为多数情况下的首选方案,并提出了数据预处理、索引优化、查询优化等策略以提升性能。通过这些方法,即使在资源受限的环境中也能实现高效的向量检索。
|
3月前
|
存储 编译器 C语言
【C语言篇】数据在内存中的存储(超详细)
浮点数就采⽤下⾯的规则表⽰,即指数E的真实值加上127(或1023),再将有效数字M去掉整数部分的1。
370 0
|
22天前
|
存储 C语言
数据在内存中的存储方式
本文介绍了计算机中整数和浮点数的存储方式,包括整数的原码、反码、补码,以及浮点数的IEEE754标准存储格式。同时,探讨了大小端字节序的概念及其判断方法,通过实例代码展示了这些概念的实际应用。
45 1
|
26天前
|
存储
共用体在内存中如何存储数据
共用体(Union)在内存中为所有成员分配同一段内存空间,大小等于最大成员所需的空间。这意味着所有成员共享同一块内存,但同一时间只能存储其中一个成员的数据,无法同时保存多个成员的值。