我继续在许多论坛和许多博客上看到一个页面的组成如下所示: 页面大小:16 x 512B = 8192B 页眉:= 96B 最大 In_Row 行:= 8060B
这留下 (8192 - 96 - 8060)B = 36B。
好的,这是合乎逻辑且正确的。我的问题是:为什么那么多人说剩下的36B是留给slot array的?
显然,插槽数组在页面上每行给出 2B;所以,它可以小到 2B,大到 1472B:
2B:1 行 * 2B = 2B
1472B:8096B = n*9B(带开销的最小行大小……想想单个 TINYINT 列)+ n*2B(每行槽阵列成本)=> 8096 = 11n => n = 8096 / 11 = 736。
736*2B = 1472B。
由于 14B 版本标签,这使我达到 20。
USE master ;
GO
CREATE DATABASE test ;
GO
USE test ;
GO
ALTER DATABASE test
SET ALLOW_SNAPSHOT_ISOLATION ON ;
GO
ALTER DATABASE test …
Run Code Online (Sandbox Code Playgroud) sql-server-2008 storage-engine data-pages database-internals
在 SQL Server 中,为什么一个 tinyint 以 9B 存储在行中。出于某种原因,在 NULL 位图掩码的末尾似乎还有一个额外的字节。
使用临时数据库; 走 创建表 tbl ( 我 TINYINT 不为空 ); 走 插入 tbl (i) 值 (1) ; 走 DBCC IND ('tempdb','tbl',-1) ; 走 DBCC TRACEON (3604) ; -- 页面转储将进入控制台 走 DBCC 页面 ('tempdb',1,168,3); 走
结果(由于 DBCC PAGE 首先显示最低有效字节,因此我颠倒了字节):
Record Size = 9B
10000500 01010000 00
TagA = 0x10 = 1B
TagB = 0x00 = 1B
Null Bitmap Offset = 0x0005 = 2B
Our integer column = 0x01 = 1B
Column Count …
Run Code Online (Sandbox Code Playgroud) 我的一个朋友今天告诉我,我可以简单地分离然后重新附加数据库,而不是弹跳 SQL Server,此操作将从缓存中清除给定数据库的页面和计划。我不同意并在下面提供我的证据。如果您不同意我的观点或有更好的反驳,请务必提供。
我在这个版本的 SQL Server 上使用 AdventureWorks2012:
选择@@版本; Microsoft SQL Server 2012 - 11.0.2100.60 (X64) Windows NT 6.1(内部版本 7601:Service Pack 1)上的开发人员版(64 位)
加载数据库后,我运行以下查询:
首先,运行在这里找到的 Jonathan K 的 AW 增肥脚本:
--------------------------- -- 第 1 步:Bpool 的东西? --------------------------- 使用 [AdventureWorks2012]; 走 选择 OBJECT_NAME(p.object_id) AS [ObjectName] , p.object_id , p.index_id , COUNT(*) / 128 AS [缓冲区大小(MB)] , COUNT(*) AS [buffer_count] 从 sys.allocation_units AS INNER JOIN sys.dm_os_buffer_descriptors AS b ON a.allocation_unit_id = b.allocation_unit_id INNER JOIN sys.partitions AS p ON a.container_id = …
所以,每次我读到数据文件缩小会导致碎片化,或者开发人员对他所看到的 95% 的碎片是所有生活痛苦的原因大加赞赏时,我想知道问题到底是什么。我们不再将单个磁盘专用于任何事情,而是从 EFD、15k、10k 轴的自动分层池中分割出 LUN;然而,我从未见过任何测试考虑到一旦我们忽略了一个磁盘测试模型,逻辑碎片是否意味着任何性能方面的明智。
也许 bpool 的性能会更糟糕,但如果我认为我的 IO 子系统仍然在不到 20 毫秒的时间内返回我需要的东西,并进一步假设我拥有的每个索引都碎片化了,这真的很重要吗?也就是说,在 TB 级索引的世界中,保留碎片比修复碎片更便宜,还是仅使用堆并在其上构建非聚集索引更便宜?我想还需要更多的研究;但我只是想把这个想法扔在这里供讨论。
使用临时数据库; 走 删除表 tbl ; 走 创建表 tbl ( i SQL_VARIANT 非空 ); 走 插入 tbl (i) 值 (1) ; 走 从 tbl 中选择我; 走 DBCC IND ('tempdb','tbl',-1) ; 走 DBCC TRACEON (3604) ; -- 页面转储将进入控制台 走 DBCC 页面 ('tempdb',1,157,3) ; 走
-- 示例 1:使用聚集索引
CREATE TABLE tbl5
(
i VARCHAR(900) NOT NULL
) ;
GO
CREATE CLUSTERED INDEX CIX_tbl5
ON tbl5 (i ASC) ;
GO
INSERT INTO tbl5
( i )
VALUES
( REPLICATE('a' , 900) )
, ( REPLICATE('b' , 900) )
, ( REPLICATE('c' , 900) )
, ( REPLICATE('d' , 900) )
, ( REPLICATE('e' , 900) )
, ( REPLICATE('f' , 900) )
, ( REPLICATE('g' , 900) )
, ( REPLICATE('h' , 900) ) -- 900 …
Run Code Online (Sandbox Code Playgroud)