如果它在索引末尾添加一行,则只会为该行分配一个新页面,而不是拆分当前的末尾页面。下面是对此的实验证据(使用%%physloc%%
需要SQL Server 2008 的功能)。另请参见此处的讨论。
CREATE TABLE T
(
id int identity(1,1) PRIMARY KEY,
filler char(1000)
)
GO
INSERT INTO T
DEFAULT VALUES
GO 7
GO
SELECT sys.fn_PhysLocFormatter(%%physloc%%)
FROM T
GO
INSERT INTO T
DEFAULT VALUES
GO
SELECT sys.fn_PhysLocFormatter(%%physloc%%)
FROM T
GO
DROP TABLE T
退货(您的结果会有所不同)
(1:173:0) /*File:Page:Slot*/
(1:173:1)
(1:173:2)
(1:173:3)
(1:173:4)
(1:173:5)
(1:173:6)
(1:110:0) /*Final insert is on a new page*/
不过,这似乎仅适用于叶节点。通过运行以下内容并调整TOP
值可以看出这一点。对我来说,622/623
是要求一个和两个第一级页面之间的切入点(如果启用了快照隔离功能,可能会有所不同吗?)。它确实以平衡的方式拆分页面,导致该级别的空间浪费。
USE tempdb;
CREATE TABLE T2
(
id int identity(1,1) PRIMARY KEY CLUSTERED,
filler char(8000)
)
INSERT INTO T2(filler)
SELECT TOP 622 'A'
FROM master..spt_values v1, master..spt_values v2
DECLARE @index_info TABLE
(PageFID VARCHAR(10),
PagePID VARCHAR(10),
IAMFID tinyint,
IAMPID int,
ObjectID int,
IndexID tinyint,
PartitionNumber tinyint,
PartitionID bigint,
iam_chain_type varchar(30),
PageType tinyint,
IndexLevel tinyint,
NextPageFID tinyint,
NextPagePID int,
PrevPageFID tinyint,
PrevPagePID int,
Primary Key (PageFID, PagePID));
INSERT INTO @index_info
EXEC ('DBCC IND ( tempdb, T2, -1)' );
DECLARE @DynSQL nvarchar(max) = 'DBCC TRACEON (3604);'
SELECT @DynSQL = @DynSQL + '
DBCC PAGE(tempdb, ' + PageFID + ', ' + PagePID + ', 3); '
FROM @index_info
WHERE IndexLevel = 1
SET @DynSQL = @DynSQL + '
DBCC TRACEOFF(3604); '
EXEC(@DynSQL)
DROP TABLE T2