问一个关于数据分页的问题

bala7229291 2011-09-08 06:44:55
我在 SQL Server 2005技术内幕:存储引擎 的拆分页部分看到以下内容:

When you inspect the original page after the split, you might find that it contains either the first half of the rows from the original page or the second half. SQL Server normally moves the rows so the new row to be inserted goes on the new page. Because the rows are moving anyway, it makes more sense to adjust their positions to accommodate the new inserted row.

我自己的解释是:
当你检查拆分后的原始分页时,你可能发现它既可能有原始分页的上半部分,也可能有下半部分。 为了即将插入的新行,SQL Server通常移动一些行到新的分页。因为这些行总是要移动的,所以这些移动的行调整位置以便新记录插入其中将显得更高效。


文中提到拆分之后的原始分页上既可能有拆分之前原始分页的上半部分和下半部分,但做了几个测试,都没有遇到会在拆分后的原始分页里留下拆分前原始分页的下半部分的数据。

是否我理解这句话有误,还是测试的例子不对,望高手给予指点,如有测试记录最好
...全文
105 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
gold_water 2011-09-09
  • 打赏
  • 举报
回复
具体应用具体对待,不要死套那些玩意。
bala7229291 2011-09-08
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 fredrickhu 的回复:]
我没有看懂意思 呵呵
[/Quote]

可能是我表达不够好

我就是测试了一下一个数据页在拆分时候的情况,按理说,拆分前的数据页应该对半分开,但是有个问题,到底是上半部分留在原来的分页,还是下半部分留在原来的分页,技术内幕里说到的意义我理解为都有可能,可是我的测试在上下两部分都增加了记录,可是得到的情况都一样,都是上半部分留在原来的分页,下半部分分到了新的分页,我就想知道,如果技术内幕上说的属实的话,要什么时候才会出现上半部分被分配到新的分页,而下半部分留在原来的分页
--小F-- 2011-09-08
  • 打赏
  • 举报
回复
我没有看懂意思 呵呵
bean_sql 2011-09-08
  • 打赏
  • 举报
回复

不懂,帮顶....
bala7229291 2011-09-08
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 qianjin036a 的回复:]
从原文来看,似乎是表明移动行与填充有些关系.为了使得行的填充合理,它总是会移动的,只不过迟早不同而已.楼主的测试不知道是什么样的,或许是因为你已有的行数太少了,不足以使SQLSERVER觉得为了合理分布而需要移动那些行.
[/Quote]
其实我的测试也是在技术内幕的列子上的

use test;
go

if object_id('bigrows', 'U') is not null
drop table bigrows;
go

/*
测试设计

1.创建一个简单的表,两个字段即可,一个定长,一个变长,使之具有普遍性
2.第一个字段使用整形,并作为主键
3.第二个字段使用变长,取值1600字符,这样能用少量的记录行就能填充一个数据页
*/
create table bigrows
(
a int primary key,
b varchar(1600)
);
go

/*
记录长度计算

假设变长列全部占用

record-len = TagA + TagB + FSize + FData + Ncol + Nullbits
+ VarCount + VarOffset + VarData + RowOffset
= 1 + 1 + 2 + 4 + 2 + 1 + 2 + 2 + 1600 + 2
= 1617 byte

一个数据页可以容纳的记录行数

row-count = 8096 / 1617 ≈ 5

为了使得聚集索引还有插入的空间 a 使用等差数列 差为5 以5开头
*/
insert into bigrows
values(5, replicate('a', 1600));

insert into bigrows
values(10, replicate('b', 1600));

insert into bigrows
values(15, replicate('c', 1600));

insert into bigrows
values(20, replicate('d', 1600));

insert into bigrows
values(25, replicate('e', 1600));

--用dbcc ind命令查看数据页情况
dbcc ind(test, bigrows, -1)
go
/*
执行结果

PageFID PagePID IAMFID IAMPID IndexID PageType IndexLevel
------- ----------- ------ ----------- ----------- -------- ----------
1 78 NULL NULL 1 10 NULL
1 41 1 78 1 1 0

只显示了有用的列
得到聚集索引叶子层的一个数据页 1:41
*/

--查看数据页详细情况
dbcc traceon(3604);
go
dbcc page(test, 1, 41, 1);
go
/*
Row - Offset
4 (0x4) - 6556 (0x199c) ---a = 25
3 (0x3) - 4941 (0x134d) ---a = 20
2 (0x2) - 3326 (0xcfe) ---a = 15
1 (0x1) - 1711 (0x6af) ---a = 10
0 (0x0) - 96 (0x60) ---a = 5
*/

--插入第六行导致数据页拆分
insert into bigrows
values(7, replicate('x', 1600));

dbcc ind(test, bigrows, -1);
go
/*

得到 1:126
1:41
*/

--先查看原始分页的情况
dbcc page(test, 1, 41, 1);
go
/*
Row - Offset
2 (0x2) - 1711 (0x6af) a = 10
1 (0x1) - 3326 (0xcfe) a = 7
0 (0x0) - 96 (0x60) a = 5
*/
--在查看新分页
dbcc page(test, 1, 126, 1);
go
/*
Row - Offset
2 (0x2) - 3326 (0xcfe) a = 25
1 (0x1) - 1711 (0x6af) a = 20
0 (0x0) - 96 (0x60) a = 15
*/

/*
可以看出原始分页发生了拆分,前两行留在了原始分页
page 41,新记录 a = 7 这两行的中间

原始分页的后三行被移动到了新的分页 page = 126
*/

--改变插入的位置,重头来,插入 a = 22的记录
--得到的结果是前三行依然留在原始分页,后两行移动到新分页,新记录插在它们中间
--过程省略

--疑问:什么时候才能出现记录的前半段被移动到新页呢?
-晴天 2011-09-08
  • 打赏
  • 举报
回复
从原文来看,似乎是表明移动行与填充有些关系.为了使得行的填充合理,它总是会移动的,只不过迟早不同而已.楼主的测试不知道是什么样的,或许是因为你已有的行数太少了,不足以使SQLSERVER觉得为了合理分布而需要移动那些行.
bala7229291 2011-09-08
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 chuanzhang5687 的回复:]
膜拜楼主!技术内幕都看英文版的!
[/Quote]
不是了,因为中文版的这段翻译有点问题,我对照英文版看一看是否有什么问题
chuanzhang5687 2011-09-08
  • 打赏
  • 举报
回复
膜拜楼主!技术内幕都看英文版的!

34,575

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧