什么是转发记录指针?

转发记录指针是堆表中特有的数据存储机制。

当你修改了某个数据页中的一行时,如果该行所在的数据页已经无法存放其修改后的行,

SQL Server会把这行数据移动到一个新的数据页上面去,并在原来的位置留下一个”记录转发指针”,指向到数据行新的位置。

图一

滥用记录转发指针的后果

转发记录指针是个非常麻烦的东西,对数据读取的性能百害无一利,

试想在一个满是转发指针记录的表中查找数据时,你需要根据这些转发指针记录在不同的数据页上跳来跳去,对性能的影响可想而知。

甚至连SQL Server自己也意识到这个机制并不完美,在未来的版本中可能不再存在。(《Inside SQL Server 2008》 Page296 )

下文我们将举个例子来说明转发指针记录如何影响性能。

--查询某个数据库中转发“指针记录大于”0的表

USE databasename

SELECT OBJECT_NAME(object_id) AS object_name

,page_count

,avg_page_space_used_in_percent

,record_count

,forwarded_record_count

FROM sys.dm_db_index_physical_stats (db_id(), NULL ,null, null,'DETAILED')

WHERE forwarded_record_count > 0 order by forwarded_record_count desc

图二

如图二显示,该表(table_name)一共有700页,但转发指针记录竟然达1750个,

这么多的转发指针记录,你知道这意味着什么吗?

在回答之前我们先可以思考一个问题:如果一个查询要对该表做一次全表扫描,逻辑读应该是多少?

我们来查询下:

set statistics io on

select * from table_name

图三

各位读者有什么感想,一张才700页的表竟然逻辑读了2450次,是实际数据页数量的3倍之多!

如何清除表中转发指针记录

既然转发指针记录的产生无法避免,是不是意味着我们就没有办法避免由此带来的性能问题呢?

我们知道,转发指针记录是因为当前页没有足够的空间容纳该行,致使行被迁出到新页中,

如果这个行的大小被收缩到满足页的容量或者页中有剩余的空间能够存储改行时,转发指针记录将会被清除,

如此说来,消除转发指针记录的方式还很多,比如:重建表、数据库压缩、创建聚集索引等所有重构表存储结构的操作。

本文以创建聚集索引作为推荐方式向大家介绍:

我们现在创建下聚集索引,从而让表的存储空间重新组织,

--创建聚集索引后查询

create index Clu_tname_labl on table_name(col1,col2)

然后我们再来看看这个查询:

set statistics io on

select * from table_name

逻辑读取由原来2450减少到543次,相比之前提升了将近4倍。

结论

上文介绍了转发指针记录的形成、对性能的影响及如何消除转发转发指针记录。

在实际环境中,我们或许不会专门去查找某个表的转发指针记录,但当遇到某个表查询性能较差时,作为一个性能影响的因素,我们不应该忽视。

最后,希望本文能够帮助到你!

SQL Server转发记录指针的坏味道的更多相关文章

  1. oracle 、mysql、 sql server使用记录

    oracle .mysql. sql server使用记录 mysql常用命令: mysqld --启动mysql数据库 show databases; -- 查看数据库 use database; ...

  2. 使用SQL Server Audit记录数据库变更

        最近工作中有一个需求,就是某一个比较重要的业务表经常被莫名其妙的变更.在SQL Server中这类工作如果不事前捕获记录的话,无法做到.对于捕获变更来说,可以考虑的选择包括Trace,CDC. ...

  3. SQL Server之记录筛选(top、ties、offset)汇总

    一.TOP 筛选 如果有 ORDER BY 子句,TOP 筛选将根据排序的结果返回指定的行数.如果没有 ORDER BY 子句,TOP 筛选将按照行的物理顺序返回指定的行数. 1. 返回指定数目的行 ...

  4. SQL Server 表,记录 死锁解决办法

    我自己的数据库表记录死锁后的 根据以下资料的 解决方案: 1. 先根据以下语句 查询 哪些表被 死锁,及 死锁的  spid SELECT request_session_id spid,OBJECT ...

  5. 【SQL Server 问题记录】A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible.

    本文涉及的相关问题,如果你的问题或需求有与下面所述相似之处,请阅读本文 A network-related or instance-specific error occurred while esta ...

  6. 新手C#SQL Server使用记录2018.08.10

    主键(PrimaryKey):主键就是每个数据行(记录)的唯一标识,不会有重复值的列(字段)才能当做主键.一个表可以没有主键,但是这样会很难处理表,因此一般情况表都要设置主键. 主键有两张选用策略,分 ...

  7. 【Vegas原创】查询SQL Server更改记录的语句

    指定数据库,然后: select Name,Create_date,Modify_Date from sys.objects where type in ('U','P', 'V','F', 'TR' ...

  8. SQL Server学习记录之获取每月每季度每年第一天和最后一天

    DECLARE@dtdatetime SET@dt=GETDATE() DECLARE@numberint --1.指定日期该年的第一天或最后一天 --A. 年的第一天 SELECTCONVERT() ...

  9. Sql Server删除数据表中重复记录 三种方法

    本文介绍了Sql Server数据库中删除数据表中重复记录的方法. [项目]数据库中users表,包含u_name,u_pwd两个字段,其中u_name存在重复项,现在要实现把重复的项删除![分析]1 ...

随机推荐

  1. 京东B2B的4种供销模式

    B2B的4种供销模式,以京东商城为例: FBP     京东给商家一个独立操作的后台, 商家五地入库(北京,上海,广州,成都,武汉),从仓储 到配送 到客服都是京东来操作, 京东本身自营的产品所有能享 ...

  2. Ruby-Array数组

    1.创建数组 a=Array.new(6,obj=nil)  #=> [nil, nil, nil, nil, nil, nil] 设置默认值 a=Array.new(6)           ...

  3. java基础七 [图形用户接口](阅读Head First Java记录)

    到目前为止我们接触的都是Java的命令行,但是为了让用户使用,必须有图形化界面,所以这章主要讲的是怎么使用GUI(图形用户接口)   创建一个GUI:javax.swing.* 本章讲的布局相关内容都 ...

  4. if条件里比较浮点数

    晚上看会儿书,基础的东西,很多都不熟练,不得不佩服那些人真的很厉害,为啥会想到那些,我这傻脑袋是想不到,暂时...... 比较3.3333与3 #!/bin/bash var1=`echo " ...

  5. Solr Zookeeper ACL权限配置

    首先注意:在配置ACL的时候,请关闭solr运行实例!!否则可能对集群造成不可恢复的损坏 开始: 1.修改solr.xml,在solrCloud节点添加,告诉solr要使用的provider: < ...

  6. 初识ASP.NET CORE:一、HTTP pipeline

    完整的http请求在asp.net framework中的处理流程: Asp.Net HttpRequest--> HTTP.exe--> inetinfo.exe(w3wp.exe)-& ...

  7. coredump调试的使用

    一,什么是coredump 跑程序的时候经常碰到SIGNAL 或者 call trace的问题,需要定位解决,这里说的大部分是指对应程序由于各种异常或者bug导致在运行过程中异常退出或者中止,并且在满 ...

  8. ICE系列之3对象接口定义语言——slice

         Slice 定义由编译器编译到特定的实现语言 .编译器把与语言无关的定 义翻译成针对特定语言的类型定义和 API.开发者使用这些类型和 API 来 提供应用功能,并与 Ice 交互.用于各种 ...

  9. Ext开场布局设计Viewport

    //加载dwr dwr.engine.setAsync(false); //***************************************框架定义部分***************** ...

  10. 用js识别是否360浏览器

    360浏览器说实话比较恶,以前可以通过内核返回的字符串判定是否包含"360"字样的方法来判定 如以下代码 window.navigator.userAgent.indexOf('3 ...