Update语句到底是如何操作记录的?

  经常会听到一些开发的朋友说,Update语句的操作原理是:先删后加!今天偶然想起这句话,索性验证一下。参考下面示例:

USE CSDN
go

--新添加一个文件组和文件
ALTER DATABASE CSDN
    ADD FILEGROUP fg20140313
go

ALTER DATABASE CSDN
ADD FILE
(
    NAME = 'fg20140313',
    FILENAME = 'd:\db\fg20140313.ndf'
) TO FILEGROUP fg20140313
go

--创建测试表:UpdatePage
IF OBJECT_ID('dbo.UpdatePage', 'U') IS NOT NULL
    DROP TABLE dbo.UpdatePage
GO

CREATE TABLE dbo.UpdatePage
(
       id INT IDENTITY(1,1) NOT NULL PRIMARY KEY,
       NAME CHAR(10),
       remark NVARCHAR (200)
) ON fg20140313
GO

--插入2条测试数据
INSERT dbo.UpdatePage VALUES('Shawn' , 'This is a test' )
INSERT dbo.UpdatePage VALUES('Lucy' ,  'That is a test' )

--此表分配的页情况如下:UpdatePage表分配了一个IAM页(3:9)和一个数据页(3:8)
DBCC TRACEON (3604)
DBCC IND(CSDN, UpdatePage, 1)


图1.

--我们直接看一下8号页上的数据情况,此面包含的2条记录槽号偏移量分别是:96,149 (10进制表示)
 DBCC PAGE (CSDN, 3, 8 , 2)
图2.1 --停止SQL SERVER服务,把d:\db\fg20140313.ndf文件Copy出来,用WinHex查看,可以根据槽号来验证一下2条记录的存储位置

图2.2 --启动SQL Server服务,更新定长字段NAME UPDATE dbo.UpdatePage SET NAME = 'xxxx' WHERE ID = 1 --保存数据到硬盘 CHECKPOINT
--查看槽号位置
DBCC
PAGE (CSDN, 3, 8 , 2)

图3.1
图3.2

--启动SQL Server服务,更新变长字段remark
UPDATE dbo.UpdatePage
SET remark = 'remark'
WHERE ID = 1
--保存数据到硬盘
CHECKPOINT
DBCC PAGE (CSDN, 3, 8 , 2)

图4.1

图4.2

--
启动SQL Server服务,再次更新变长字段remark UPDATE dbo.UpdatePage SET remark = 'This is a long text.' WHERE ID = 1 --保存数据到硬盘 CHECKPOINT

DBCC PAGE (CSDN, 3, 8 , 2)



 --结论:

#1.对于更新固定长度的字段,直接update字段值;
#2.对于更新可变长度的字段,当字段存储字符变小时,可能会“先删后加”(这种情况笔者也测试产生过),也可能不会(本例中的就是这种情况)。会的话主要考虑了存储空间的利用,减小碎片;而不会的话,主要考虑了效率。
#3.“先删后加”逻辑上相当于先delete记录再insert记录;物理上并未delete记录,而是更新了Slot中的偏移量并Copy未变化字段Insert到新位置。
#4.从性能上讲,update定长字段的效率会好些.但在设计表时,用定长还是变长字段,还是应该根据业务来定。
#5.最后一句话:Update是“先删后加”不是绝对的。

 

 

posted @ 2014-03-16 21:47  wwwwgou  阅读(600)  评论(1编辑  收藏  举报