我试图了解如何在SQL Server中创建页面。 我做了一个非常简单的例子:
-- 0 pages
CREATE TABLE TMP_1(
id int)
-- 2 pages
INSERT INTO TMP_1
VALUES(1)
-- 3 pages
SELECT *
INTO TMP_2
FROM TMP_1
在第一张桌子上,TMP_1没有页面,这是相当直观的,因为没有数据。插入1行后,有两页。其中一个存储数据,但第二个是什么?
表TMP_2应该与TMP_1相同但它有3页,为什么?
我使用以下代码检查页数:
SELECT
t.NAME AS TableName,
p.rows AS RowCounts,
SUM(a.total_pages) AS TotalPages,
SUM(a.used_pages) AS UsedPages,
(SUM(a.total_pages) - SUM(a.used_pages)) AS UnusedPages
FROM
sys.tables t
INNER JOIN
sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN
sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN
sys.allocation_units a ON p.partition_id = a.container_id
WHERE
t.NAME NOT LIKE 'dt%'
AND t.is_ms_shipped = 0
AND i.OBJECT_ID > 255
AND t.name LIKE 'TMP%'
GROUP BY
t.Name, p.Rows
ORDER BY
t.Name
答案 0 :(得分:4)
在第一张桌子上,TMP_1没有页面,这是相当直观的,因为没有数据
Sql server将仅在第一次插入时分配页面
插入1行后有两页。其中一个存储数据,但第二个是什么?
这称为IAM Page ..
SQL Server使用索引分配映射来跟踪哪些页面已分配给哪个分配单元。它们存储在特殊的IAM页面中。
每个IAM页面覆盖文件中64000个范围的区域,即所谓的GAM间隔。如果单个分配单元需要多个IAM页面,则形成双链表,即IAM链。
见下面的演示..
create table t1
(
id int
)
drop table t1
insert into t1
values(1)
DBCC TRACEON (3604);
DBCC IND('PerformanceV3','t1',-1)
剥离输出:
iam_chain_type PartitionID PageType
In-row data 72057594048217088 10
In-row data 72057594048217088 1
第三个问题:
表TMP_2应该与TMP_1相同但它有3页,为什么?
这是一个数据页面,我最好的猜测是假设,这就是方法 select into在内部工作,当你插入时,SQL总是可以在需要时动态创建页面,但是使用select into,它又创建了一个数据页面。
至于为什么,select into显示所使用的所有三个页面:
我相信分配DMV会捕获所有页面分配,但我们正在讨论这里使用的......更准确地说,下面的DBCC命令可以看到..
dbcc traceon(3604)
dbcc ind('performancev3','t2',-1)
dbcc page(0,1,36639,3)
参考文献:
http://sqlity.net/en/2315/index-allocation-map/
http://www.sqlskills.com/blogs/paul/inside-the-storage-engine-using-dbcc-page-and-dbcc-ind-to-find-out-if-page-splits-ever-roll-back/