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是“先删后加”不是绝对的。

 

 

你可能感兴趣的:(update)