所以,假设我有一个页面,我打算将其拆分。
使用大师; 去 IF DATABASEPROPERTYEX (N'Pages', N'Version') > 0 开始 ALTER DATABASE Pages SET SINGLE_USER WITH ROLLBACK IMMEDIATE; 删除数据库页面; 结尾 去 创建数据库页面; 去 IF EXISTS(SELECT object_id FROM sys.objects WHERE name = 'PageSplit') 开始 删除表 PageSplit ; 结尾 使用页面; 去 创建表 PageSplit ( c1 整数标识 , c2 VARCHAR(2000) 默认复制('b' , 1000) ); 去 创建唯一的聚集索引 CIX_c1 在 dbo.PageSplit 上 ( [c1] 升序 ); 去 插入 PageSplit 默认值; 去7 DBCC IND(Pages,PageSplit,-1); 去 DBCC TRACEON(3604) ; 去 DBCC 页面(页面,1,231,3); 去 -- m_freeCnt = 977
此时,我只需要像这样更新一行,我就会得到一个拆分:3 行到一页,4 行到另一页:
更新分页 SET c2 = REPLICATE('b', 2000) 其中 c1 = 1 ; 去
所以,我的问题是:更新何时发生:在页面拆分之前还是之后?我假设它发生在分裂之后。
我附上了 SQL Profiler 和 DBCC IND 的输出。请注意,更新后的行保留在原始页面上。
我应用了 SQL Kiwi 的建议。在这里查看结果:
这
UPDATE
会在拆分之后发生,因为从数据状态的角度来看,SQL Server 永远不会覆盖进程中的另一个当前分配的行。此外,如果 SQL Server 确实覆盖了另一行的一部分,并且必须移动该行,它就不知道要将哪些数据复制到新页面。该行的副本可以保存在内存中的临时缓冲区中......这......正是数据页的定义。
所以拆分过程如下:
最后,
UPDATE
发生了,它总是可以自由覆盖页面的未分配部分。