SQL Server存储内幕系列之二:分区和分配单元

源文档 <http://www.sqlservercentral.com/blogs/livingforsqlserver/archive/2010/12/16/sql-server-storage-internals-part-2-partitions-and-allocation-units.aspx>

在讨论不同类型的页面前,需要了解以下系统视图之间的关系:sys.objects, sys.partitions, sys.allocation_units and sys.system_internals_allocation_units

Case 1 (simple table with record size less than 8000 bytes and no LOB data) :

image1.jpg

When a table is created (Heap), by default all its pages are aligned in one partition. Partition is a unit of data organization.

当表创建时,默认其所有页面分配在一个分区(分区是组织数据的单位),添加了非聚集索引,分区框架和与其相关的索引页面逻辑上分配到各自的分区。基于存储的数据,一个分区有3种类型的页组面:IN_ROW_DATA页,ROW_OVERFLOW_DATA页和LOB_DATA页,这些页组也称为“分配单位”。

以下是它们的区别:

1. IN_ROW_DATA (默认) : 若一个表设计简单(即行记录小于8000字节,不存在LOB数据类型),页中存储的所有数据以IN_ROW_DATA标记。

2. ROW_OVERFLOW_DATA :若表中包含3个varchar(4000)的数据类型,当插入大于8000字节的记录时,其数据将移动到ROW_OVERFLOW_DATA页。

3. LOB_DATA : LOB数据不与数据页一起存储,LOB数据存储在LOB_DATA的特殊页,数据页包含16字节的指针用于查找LOB_DATA页面。

下面通过创建一个示例表(其表记录小于8000字节,不包含LOB数据类型)

CREATE TABLE tExample1(

strEmpCode char(6),

strName varchar(100),

strDept varchar(10),

strCity varchar(100))

GO

以下查询输出表对象的相关信息:
select object_id, name, type_desc from sys.objects where name = 'tExample1'

go

示例输出: 

object_id name type_desc

2089058478 tExample1 USER_TABLE

正如前面提到的,表逻辑上分配在一个容器(也叫做“分区”),以下查询输出tExample1表对象的分区信息:

select object_name(object_id), object_id, partition_id, hobt_id, partition_number, rows

from sys.partitions

where object_name(object_id) = 'tExample1'

go

示例输出:

TableName object_id partition_id hobt_id partition_number rows

tExample1  2089058478 72057594038648800 72057594038648800 1 0

Object_id : 表对象标识

Partition_id : 表对象的分区标识

Hobt_id : 存储数据的heap或B树的标识

提示:一张表有一个或多个分区,每一个分区最大有3种分区单元

以下查询输出分区编号为72057594038648800的Allocation_unit详细信息

select *

from sys.allocation_units

where container_id = 72057594038648832

go

allocation_unit_id type type_desc container_id data_space_id total_pages used_pages data_pages

72057594042646500 1 IN_ROW_DATA 72057594038648800 1 0 0 0

下面用一条查询输出:

select so.name, so.object_id, sp.index_id, sp.partition_id, sp.hobt_id, sa.allocation_unit_id, sa.type_desc, sa.total_pages

from sys.objects so

inner join sys.partitions sp on so.object_id = sp.object_id

inner join sys.allocation_units sa on sa.container_id = sp.hobt_id

where so.name = 'tExample1'

go

Sample output :

name object_id index_id partition_id hobt_id allocation_unit_id type_desc total_pages

tExample1 2089058478 0 72057594038648800 72057594038648800 72057594042646500 IN_ROW_DATA 0

Case 2:

本例详细描述对象Object,分区 Partition 和分配单位Allocation_unit 的概念

首先创建包含LOB列且行大小大于8000的表

create table tExample2(

strId int identity(1,1) PRIMARY KEY,

strdeptcode char(10),

strComment1 varchar(4000),

strComment2 varchar(4000),

strComment3 varchar(4000),

strLongText varchar(max))

go

创建非聚集索引:
create nonclustered index nci_tExample2_strdeptcode on tExample2(strDeptCode)

go

接着插入2条记录:

insert into tExample2(strDeptCode, strComment1, strComment2, strComment3, strLongText)

values('DEPT01',replicate('a',4000),replicate('b',4000), replicate('c',4000), replicate('d',10000))

GO 2

以下查询将输出所有分区的信息:

select so.name, so.object_id, sp.index_id, sp.partition_id, sp.hobt_id, sa.allocation_unit_id, sa.type_desc, sa.total_pages

from sys.objects so

inner join sys.partitions sp on so.object_id = sp.object_id

inner join sys.allocation_units sa on sa.container_id = sp.hobt_id

where so.name = 'tExample2'

go

name        object_id        index_id        partition_id        hobt_id        allocation_unit_id        type_desc        total_pages

tExample2        277576027        1        72057594039173120        72057594039173120        72057594040352768        IN_ROW_DATA        4

tExample2        277576027        1        72057594039173120        72057594039173120        72057594040483840        LOB_DATA        3

tExample2        277576027        1        72057594039173120        72057594039173120        72057594040418304        ROW_OVERFLOW_DATA        3

tExample2        277576027        2        72057594039238656        72057594039238656        72057594040549376        IN_ROW_DATA        2

说明:

Name: 表对象名称

Object_id: 表对象标识

Index_id: 1为聚集索引,2为非聚集索引

Partition_id, hobt_id:由于表存在聚集索引和非聚集索引,所以有两个分区标识

Allocation_unit_id: 聚集索引分区包含3个分配单元,非聚集索引分区包含1个分配单元
Total_pages: 页数

下面描述上面的结构:

image4.jpg
小结:

本篇文章我们介绍了表、分区及分配单元间的关系,也说明了具有多个分区或分配单元的数据的组织方式。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/355374/viewspace-683202/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/355374/viewspace-683202/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值