0
和OVERFLOW DATA 一样,数据页会有一个pointer指向LOB root structure,在LOB root structure上,又会分别指向其他LOB data page。如果数据超过32KB,LOB root structure又会引入中间层,像INDEX中的B tree一样。
当Column为NVARCHAR(MAX)且16000字符串(实际长度为32000)的时候,SQL server不会单独开辟一个新的page去存储LOB root structure。相反,LOB pointer会存在当前page。1个IN_ROW数据页,4个LOB 数据页。指针留在第一个数据页。
DBCC PAGE第一个数据页,可以看到BLOB Inline Root。其中,LOB pointer和ROW_OVERFLOW的pointer类似,如下
page number按照前一个文章的方法,实际应该是0x98501,即623873。同理可以拿到剩下3个pointer。
d0 3e000002 850900
01 000000
38 5e000003 850900
01 000000
00 7d000037 520900
01 000000
可能是对deprecated 数据类型支持不好,对于TEXT直接就开辟一个新的page为LOB root structure。DBCC PAGE LOB root structure,可以看到LOB pointer。
在这个例子中,只有两个page。一个是IAM,另外一个就是数据页,没有单独的LOB page。
DBCC page数据页,可以看到BLOB Inline Data。
参考:
Posted on
Tuesday, February 14, 2017
by
醉·醉·鱼
and labeled under
sql
,
sql server internals
直接上测试脚本。LOB可以存储VARCHAR(MAX), TEXT, IMAGE这些数据类型。但是各个类型的behavior又不太一样。和OVERFLOW DATA 一样,数据页会有一个pointer指向LOB root structure,在LOB root structure上,又会分别指向其他LOB data page。如果数据超过32KB,LOB root structure又会引入中间层,像INDEX中的B tree一样。
NVARCHAR(MAX)
IF OBJECT_ID('LobData') IS NOT NULL
DROP TABLE dbo.LobData
create table dbo.LobData
(
ID int not null,
Col1 nvarchar(max) null
);
insert into dbo.LobData(ID, Col1)
values (1, replicate(convert(varchar(max),'a'),16000));
SELECT allocated_page_file_id as PageFID, allocated_page_page_id as PagePID,
object_id as ObjectID, partition_id AS PartitionID,
allocation_unit_type_desc as AU_type, page_type as PageType
FROM sys.dm_db_database_page_allocations(db_id('test_db'), object_id('LobData'),
null, null, 'DETAILED');
GO
DBCC TRACEON (3604);
GO
DBCC PAGE ('test_db', 1, 623876, 3);
GO
当Column为NVARCHAR(MAX)且16000字符串(实际长度为32000)的时候,SQL server不会单独开辟一个新的page去存储LOB root structure。相反,LOB pointer会存在当前page。1个IN_ROW数据页,4个LOB 数据页。指针留在第一个数据页。
DBCC PAGE第一个数据页,可以看到BLOB Inline Root。其中,LOB pointer和ROW_OVERFLOW的pointer类似,如下
- 04 00000001 00000020 1c0000 metadata
- 68 1f0000 length
- 01 850900 page number
- 01 00 file number
- 0000 slow number
page number按照前一个文章的方法,实际应该是0x98501,即623873。同理可以拿到剩下3个pointer。
d0 3e000002 850900
01 000000
38 5e000003 850900
01 000000
00 7d000037 520900
01 000000
TEXT
可能是对deprecated 数据类型支持不好,对于TEXT直接就开辟一个新的page为LOB root structure。DBCC PAGE LOB root structure,可以看到LOB pointer。
VARCHAR(MAX)
和NVARCHAR(MAX)一样的行为,当数据比较短的时候,存为BLOB Inline Root。当数据更短的时候,直接就存在当前IN_ROW page。
IF OBJECT_ID('LobData') IS NOT NULL
DROP TABLE dbo.LobData
create table dbo.LobData
(
ID int not null,
Col1 varchar(max) null
);
insert into dbo.LobData(ID, Col1)
values (1, replicate(convert(varchar(max),'a'),400));
在这个例子中,只有两个page。一个是IAM,另外一个就是数据页,没有单独的LOB page。
DBCC page数据页,可以看到BLOB Inline Data。
参考:
- http://aboutsqlserver.com/2013/11/05/sql-server-storage-engine-lob-storage/
- http://improve.dk/what-is-the-size-of-the-lob-pointer-for-max-types-like-varchar-varbinary-etc/
Post a Comment