次の表を作成しました。
CREATE TABLE dbo.TestStructure
(
id INT NOT NULL,
filler1 CHAR(36) NOT NULL,
filler2 CHAR(216) NOT NULL
);
次に、クラスター化インデックスを作成しました。
CREATE CLUSTERED INDEX idx_cl_id
ON dbo.TestStructure(id);
次に、各サイズが256バイトである30行(テーブル宣言に基づいて)を入力しました。
DECLARE @i AS int = 0;
WHILE @i < 30
BEGIN
SET @i = @i + 1;
INSERT INTO dbo.TestStructure (id, filler1, filler2)
VALUES (@i, 'a', 'b');
END;
「トレーニングキット(試験70-461):Microsoft SQL Server 2012のクエリ(Itzik Ben-Gan)」本で読んだ情報に基づきます:
SQL Serverは、データファイル内のデータをページ単位で内部的に編成します。ページは8 KB単位であり、単一のオブジェクトに属します。たとえば、テーブルまたはインデックスへ。ページは、読み取りと書き込みの最小単位です。ページはさらにエクステントに編成されます。エクステントは8つの連続したページで構成されます。エクステントからのページは、単一のオブジェクトまたは複数のオブジェクトに属することができます。ページが複数のオブジェクトに属する場合、エクステントは混合エクステントと呼ばれます。ページが単一のオブジェクトに属している場合、そのエクステントはユニフォームエクステントと呼ばれます。SQL Serverは、オブジェクトの最初の8ページを混合エクステントに保存します。オブジェクトが8ページを超えると、SQL Serverはこのオブジェクトに追加の均一エクステントを割り当てます。この構成により、小さなオブジェクトが無駄にするスペースが少なくなり、大きなオブジェクトの断片化が少なくなります。
だから、ここに最初の混合エクステント8KBページがあり、7680バイト(256バイトサイズの行を30回挿入したので、30 * 256 = 7680)、サイズチェックプロシージャを実行したサイズをチェックします-それは次の結果を返します
index_type_desc: CLUSTERED INDEX
index_depth: 1
index_level: 0
page_count: 1
record_count: 30
avg_page_space_used_in_percent: 98.1961947121324
name : TestStructure
rows : 30
reserved : 16 KB
data : 8 KB
index_size : 8 KB
unused : 0 KB
したがって、テーブル用に16 KBが予約され、最初の8 KBページはルートIAMページ用、2番目は8 KBのリーフデータストレージページ用で、〜7.5 KBの占有で、今は256バイトの新しい行を挿入します:
INSERT INTO dbo.TestStructure (id, filler1, filler2)
VALUES (1, 'a', 'b');
256バイトのスペース(7680 b + 256 = 7936は8KBよりも小さい)がありますが、同じページに格納されないため、新しいデータページが作成されますが、その新しい行は同じ古いページに収まる可能性があります、スペースと検索時間を節約できるのに既存のページに挿入することでSQL Serverが新しいページを作成するのはなぜですか?
注:ヒープインデックスでも同じことが起こります。