简介

最近在一个客户那里注意到一个计数器很高(Forwarded Records/Sec),伴随着间歇性的磁盘等待队列的波动。本篇文章分享什么是forwarded record,并从原理上谈一谈为什么Forwarded record会造成额外的IO。

存放原理

在SQL Server中,当数据是以堆的形式存放时,数据是无序的,所有非聚集索引的指针存放指向物理地址的RID。当数据行中的变长列增长使得原有页无法容纳下数据行时,数据将会移动到新的页中,并在原位置留下一个指向新页的指针,这么做的原因是由于使得当出现对Record的更新时,所有非聚集索引的指针不用变动。如图1所示。

图1.Forwarded Record示意

这种由于数据更新,只在原有位置留下指针指向新数据页存放位置行,就是所谓的Forwarded Record。

Forwarded Record如何影响IO性能?

那么Forwarded Record既然是为了提升性能存在的机制,为什么又会引起性能问题?Forwarded Record的初衷是为了对堆表进行更新时,堆表上存储位置的变化不会同时更新非聚集索引而产生开销。但对于查找来说,无论是堆表上存在表扫描,还是用于书签查找,都会成倍带来额外的IO开销,下面看一个例子。

CREATE TABLE dbo.HeapTest ( id INT, col1 VARCHAR(800) )

DECLARE @index INTSET @index = 0BEGIN TRANWHILE @index < 100000 BEGIN         INSERT  INTO dbo.HeapTest                ( id, col1 )VALUES  ( @index, NULL )SET @index = @index + 1

ENDCOMMIT

代码清单1.新建堆表并插入10万条数据

通过代码清单1创建测试表,并循环插入10万数据。此时我们来看该堆表所占用存储的页数,如图2所示。

图2.堆表空间占用

此时对该表进行更新,让原有行增长,产生Forwarded Record,此时再来看该堆表的存储。如图3所示。

图3.产生8W+的forwarded record

此时我们注意到,虽然数据仅仅占到590页,但存在8W+的forwarded record,如果我们对该表进行扫描,则会看到虽然仅仅只有590页,但需要8W+的逻辑IO,大大提升了对IO的开销压力,此外由于forwarded record页与原页往往不物理连续,因此对IOPS也存在挑战。如图4所示。

图4.不该产生的额外IO开销

而上面查询反映到性能计数器中,则呈现为如图5所示的结果。

图5.Forwarded Record计数器增长

如何解决

看到Forwarded Record计数器,就说明数据库中存在堆表,在OLTP系统中,所有的表上都应该有聚集索引。因此可以通过在表上增加聚集索引来解决该问题。

通常来讲,只有只写不读的表设置为堆表比较合适,但如果看到存在Forwarded Reocord,则说明堆表上存在读操作,那么找到该堆表,找一个合适的维护窗口时间创建聚集索引则是比较理想的选择。

如果由于其他原因无法创建聚集索引,则可以对堆表进行表重建。

转载于:https://www.cnblogs.com/CareySon/p/3829019.html

SQL Server中一个隐性的IO性能杀手-Forwarded record相关推荐

  1. 从TXT文本文档向Sql Server中批量导入数据

    因为工作的需要,近期在做数据的分析和数据的迁移.在做数据迁移的时候需要将原有的数据导入到新建的数据库中.本来这个单纯的数据导入导出是没有什么问题的,但是客户原有的数据全部都是存在.dat文件中的.所以 ...

  2. mysql物理读和逻辑读,SQL Server中STATISTICS IO物理读和逻辑读的误区

    SQL Server中STATISTICS IO物理读和逻辑读的误区 人人知道,SQL Server中可以行使下面下令查看某个语句读写IO的情形 SET STATISTICS IO ON 那么这个下令 ...

  3. 如何在SQL Server中分析存储子系统性能

    介绍 (Introduction) To improve performance, it is common for DBAs to search in each aspect except anal ...

  4. SQL SERVER中用户定义标量函数(scalar user defined function)的性能问题

    SQL SERVER中用户定义标量函数(scalar user defined function)的性能问题 原文:SQL SERVER中用户定义标量函数(scalar user defined fu ...

  5. SQL Server中一些常见的性能问题

    SQL Server中一些常见的性能问题: 1.在对查询进行优化时,应当尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.我们应当尽量避免使用 left jo ...

  6. SQL Server中的Union和Union All语句之间的差异及其性能

    SQL Server中的Union和Union All语句之间的差异及其性能 UNION vs UNION ALL 了解union和union all语句之间的差异及其性能. UNION UNION命 ...

  7. sql游标 while_用SQL Server中的排名函数替换SQL While循环和游标,以提高查询性能

    sql游标 while SQL While loop and cursor are the most common approach to repeat a statement on conditio ...

  8. sql server 性能_如何在SQL Server中收集性能和系统信息

    sql server 性能 介绍 (Introduction) In this article, we're going through many of the tools we can use fo ...

  9. nocount on_在SQL Server中设置NOCOUNT ON语句的用法和性能优势

    nocount on Have you ever noticed SET NOCOUNT ON statement in T-SQL statements or stored procedures i ...

最新文章

  1. 视频关键帧提取 java_JavaCV实现将视频以帧方式抽取
  2. PIC单片机学习之独立按键
  3. springboot aop使用_Spring Boot 的自动配置,是如何实现的?
  4. OpenCV基于LeNet-5和连接组件分析的数字识别的实例(附完整代码)
  5. 从mysql读取图片_如何从sql数据库内读取图片
  6. 当当网新用户注册界面——界面源码
  7. VB中用API实现文件拖放
  8. 工业相机选型:相机接口
  9. flash相册制作软件模板_儿童照片相册模板 怎么制作炫酷视频相册
  10. html表单-在线留言,aspcms自定义表单 在线留言修改
  11. 【书籍推荐】深入解析Windows操作系统(第4版)
  12. 联想USB键盘功能键驱动问题
  13. 想以游戏纸娃娃系统专利主张暴雪的暗黑3侵权? 先过暗黑2这关!
  14. Excel数据导入Oracle数据库
  15. 电子商务概论(农)之章节课后题
  16. js计算100以内所有奇数的和
  17. 界面清爽的SNS社交网络系统源码 PHP+MySQL(已整合IM聊天系统)
  18. UE4 UI界面的层级切换
  19. Linux CentOS 7 多网卡配置bond模式 bond1 bond5 bond6
  20. Win10安装虚拟网卡

热门文章

  1. 安装eclipse for c/c++环境
  2. cmake用法及常用命令总结(全)
  3. BZOJ5137lg4081(广义后缀自动机,set启发式合并)
  4. java实现线程间通信的四种方式
  5. oracle查询之null值转化
  6. MySQL的binlog日志
  7. 中文 iOS/Mac 开发博客列表
  8. 【Core Spring】二、装配beans
  9. POJ 2151 Check the difficulty of problems (概率dp)
  10. Wijmo 更优美的jQuery UI部件集:爱上 ThemeRoller