现在很多用户被数据库的慢的问题所困扰,又苦于花钱请一个专业的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 诊断系列

posted on 2018-03-07 16:32  xmj  阅读(141)  评论(0编辑  收藏  举报