SQL Server转发记录指针的坏味道

什么是转发记录指针?

 

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

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

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倍。

 

 

 

 

结论

 

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

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

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

时间: 2024-11-02 00:57:16

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

sql server 查询记录平均值及并排序 的语句

sql server 查询记录平均值及并排序 的语句 查询学生的平均成绩并进行排名,sql 2000用子查询完成,分平均成绩重复时保留名次空缺和不保留名次空缺两种. select t1.* , px = (select count(1) from (   select m.S# [学生编号] ,          m.Sname [学生姓名] ,          isnull(cast(avg(score) as decimal(18,2)),0) [平均成绩]   from Student

SQL Server数据库损坏检测

  在一个理想的世界中,不会存在任何数据库的损坏,就像我们不会将一些严重意外情况列入我们生活中的日常一样,而一旦这类事情发生,一定会对我们的生活造成非常显著的影响,在SQL Server中也同样如此,或许几年内您没有遇见过数据库中出现这类情况,而一旦遇见这类情况,往往伴随着数据的丢失,宕机,严重甚至您本身的职业生涯也会受到影响.因此对于这类情况,我们需要了解数据库损坏方面的知识,以便我们能够事前准备,事后能够处理.本篇文章会对数据库损坏的原因.现象.事前和事后的一些处理方法以及简单的修复方法进行

SQL Server日期计算(收藏)

server 通常,你需要获得当前日期和计算一些其他的日期,例如,你的程序可能需要判断一个月的第一天或者最后一天.你们大部分人大概都知道怎样把日期进行分割(年.月.日等),然后仅仅用分割出来的年.月.日等放在几个函数中计算出自己所需要的日期!在这篇文章里,我将告诉你如何使用DATEADD和DATEDIFF函数来计算出在你的程序中可能你要用到的一些不同日期.         在使用本文中的例子之前,你必须注意以下的问题.大部分可能不是所有例子在不同的机器上执行的结果可能不一样,这完全由哪一天是一个

SQL Server各种日期计算方法之二

上个月的最后一天 这是一个计算上个月最后一天的例子.它通过从一个月的最后一天这个例子上减去3毫秒来获得.有一点要记住,在Sql Server中时间是精确到3毫秒.这就是为什么我需要减去3毫秒来获得我要的日期和时间. SELECT dateadd(ms,-3,DATEADD(mm, DATEDIFF(mm,0,getdate()), 0)) 计算出来的日期的时间部分包含了一个Sql Server可以记录的一天的最后时刻("23:59:59:997")的时间. 去年的最后一天 连接上面的例

SQL SERVER数据库日期计算

server|数据|数据库 通常,你需要获得当前日期和计算一些其他的日期,例如,你的程序可能需要判断一个月的第一天或者最后一天. 你们大部分人大概都知道怎样把日期进行分割(年.月.日等),然后仅仅用分割出来的年.月.日等放在几个函数中计算出自己所需要的日期!在这篇文章里,我将告诉你如何使用DATEADD和DATEDIFF函数来计算出在你的程序中可能你要用到的一些不同日期. 在使用本文中的例子之前,你必须注意以下的问题.大部分可能不是所有例子在不同的机器上执行的结果可能不一样,这完全由哪一天是一个

SQL Server各种日期计算方法

server 通常,你需要获得当前日期和计算一些其他的日期,例如,你的程序可能需要判断一个月的第一天或者最后一天.你们大部分人大概都知道怎样把日期进行分割(年.月.日等),然后仅仅用分割出来的年.月.日等放在几个函数中计算出自己所需要的日期!在这篇文章里,我将告诉你如何使用DATEADD和DATEDIFF函数来计算出在你的程序中可能你要用到的一些不同日期. 在使用本文中的例子之前,你必须注意以下的问题.大部分可能不是所有例子在不同的机器上执行的结果可能不一样,这完全由哪一天是一个星期的第一天这个

保护 SQL Server 数据库的十大绝招

server|数据|数据库 1.安装最新的服务包 为了提高服务器安全性,最有效的一个方法就是升级到 SQL Server 2000 Service Pack 3a (SP3a). 另外,您还应该安装所有已发布的安全更新. 2.使用 Microsoft 基线安全性分析器(MBSA)来评估服务器的安全性 MBSA 是一个扫描多种 Microsoft 产品的不安全配置的工具,包括 SQL Server 和 Microsoft SQL Server 2000 Desktop Engine (MSDE 2

保护SQL Server的十个步骤

server 这里介绍了为提高 SQL Server 安装的安全性,您可以实施的十件事情: 1.安装最新的服务包. 为了提高服务器安全性,最有效的一个方法就是升级到 SQL Server 2000 Service Pack 3a (SP3a). 另外,您还应该安装所有已发布的安全更新. 2.使用 Microsoft 基线安全性分析器(MBSA)来评估服务器的安全性. MBSA 是一个扫描多种 Microsoft 产品的不安全配置的工具,包括 SQL Server 和 Microsoft SQL

配置SQL Server 2000选项

server SQL Server服务器的配置选项属于那种人们了解较少且经常误用的选项.当一个技术支持人员要求你按照某种方式调整一个选项.而另一个技术支持人员却要求你按照另一种完全对立的方式调整同一个选项时,你可能对这些选项的真正含义感到困惑.有关这些选项的资料很缺乏,至少可以说不够详细和清楚.在SQL Server 2000中,Microsoft减少了几个配置选项,让SQL Server动态配置它们,从而减少了几个容易混淆的地方.同时,Microsoft又为SQL Server 2000新增了