SQL Server中一个隐性的IO性能杀手-Forwarded record
简介
最近在一个客户那里注意到一个计数器很高(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相关推荐
- 从TXT文本文档向Sql Server中批量导入数据
因为工作的需要,近期在做数据的分析和数据的迁移.在做数据迁移的时候需要将原有的数据导入到新建的数据库中.本来这个单纯的数据导入导出是没有什么问题的,但是客户原有的数据全部都是存在.dat文件中的.所以 ...
- mysql物理读和逻辑读,SQL Server中STATISTICS IO物理读和逻辑读的误区
SQL Server中STATISTICS IO物理读和逻辑读的误区 人人知道,SQL Server中可以行使下面下令查看某个语句读写IO的情形 SET STATISTICS IO ON 那么这个下令 ...
- 如何在SQL Server中分析存储子系统性能
介绍 (Introduction) To improve performance, it is common for DBAs to search in each aspect except anal ...
- SQL SERVER中用户定义标量函数(scalar user defined function)的性能问题
SQL SERVER中用户定义标量函数(scalar user defined function)的性能问题 原文:SQL SERVER中用户定义标量函数(scalar user defined fu ...
- SQL Server中一些常见的性能问题
SQL Server中一些常见的性能问题: 1.在对查询进行优化时,应当尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.我们应当尽量避免使用 left jo ...
- SQL Server中的Union和Union All语句之间的差异及其性能
SQL Server中的Union和Union All语句之间的差异及其性能 UNION vs UNION ALL 了解union和union all语句之间的差异及其性能. UNION UNION命 ...
- sql游标 while_用SQL Server中的排名函数替换SQL While循环和游标,以提高查询性能
sql游标 while SQL While loop and cursor are the most common approach to repeat a statement on conditio ...
- sql server 性能_如何在SQL Server中收集性能和系统信息
sql server 性能 介绍 (Introduction) In this article, we're going through many of the tools we can use fo ...
- nocount on_在SQL Server中设置NOCOUNT ON语句的用法和性能优势
nocount on Have you ever noticed SET NOCOUNT ON statement in T-SQL statements or stored procedures i ...
最新文章
- 视频关键帧提取 java_JavaCV实现将视频以帧方式抽取
- PIC单片机学习之独立按键
- springboot aop使用_Spring Boot 的自动配置,是如何实现的?
- OpenCV基于LeNet-5和连接组件分析的数字识别的实例(附完整代码)
- 从mysql读取图片_如何从sql数据库内读取图片
- 当当网新用户注册界面——界面源码
- VB中用API实现文件拖放
- 工业相机选型:相机接口
- flash相册制作软件模板_儿童照片相册模板 怎么制作炫酷视频相册
- html表单-在线留言,aspcms自定义表单 在线留言修改
- 【书籍推荐】深入解析Windows操作系统(第4版)
- 联想USB键盘功能键驱动问题
- 想以游戏纸娃娃系统专利主张暴雪的暗黑3侵权? 先过暗黑2这关!
- Excel数据导入Oracle数据库
- 电子商务概论(农)之章节课后题
- js计算100以内所有奇数的和
- 界面清爽的SNS社交网络系统源码 PHP+MySQL(已整合IM聊天系统)
- UE4 UI界面的层级切换
- Linux CentOS 7 多网卡配置bond模式 bond1 bond5 bond6
- Win10安装虚拟网卡