テーブルとインデックスの編成

テーブルとインデックスは 8 KB のページの集合として格納されます。このトピックでは、テーブルとインデックスのページがどのように編成されているのかを説明します。

テーブルの編成

次の図に、テーブルの構成を示します。1 つ以上のパーティションに 1 つのテーブルが含まれています。また、各パーティションでは、ヒープ構造またはクラスタ化インデックス構造のいずれかの中にデータ行が含まれています。ヒープまたはクラスタ化インデックスのページは、データ行の列型に基づいて、1 つ以上のアロケーション ユニットで管理されます。

パーティションを持つテーブルの編成

パーティション

テーブル ページとインデックス ページは 1 つ以上のパーティションに格納されます。パーティションはユーザー定義のデータ編成単位です。既定では、1 つのテーブルまたはインデックスには、パーティションが 1 つだけあり、そのパーティションにすべてのテーブル ページまたはインデックス ページが格納されます。このパーティションは単一のファイル グループに所属します。保持するパーティションが 1 つのテーブルまたはインデックスは、以前のバージョンの SQL Server のテーブルやインデックスの編成構造に相当します。

テーブルやインデックスで複数のパーティションを使用している場合、データは指定した列に基づいて行方向に分割されるので、行の集合が各パーティションにマップされます。それらのパーティションは、データベース内の 1 つ以上のファイル グループに入れることができます。データに対するクエリまたは更新の実行時は、テーブルやインデックスが 1 つの論理エンティティとして扱われます。詳細については、「パーティション テーブルとパーティション インデックス」を参照してください。

テーブルまたはインデックスで使用されているパーティションを表示するには、sys.partitions (Transact-SQL) カタログ ビューを使用します。

クラスタ化テーブル、ヒープ、およびインデックス

SQL Server テーブルでは、次の 2 つのうちのいずれかの方法でパーティション内のテーブルのデータ ページを編成しています。

  • クラスタ化テーブル (クラスタ化インデックスのあるテーブル)

    データ行は、クラスタ化インデックス キーに基づく順序で格納されます。クラスタ化インデックスは、クラスタ化インデックス キーの値を基にした B ツリー インデックス構造として実装されているので、行を高速に取得できます。インデックスの各レベルのページは、リーフ レベルであるデータ ページも含め、二重リンク リストにリンクされます。ただし、あるレベルから別のレベルへ移動する際は、キー値が使用されます。詳細については、「クラスタ化インデックスの構造」を参照してください。

  • ヒープ (クラスタ化インデックスのないテーブル)

    データ行は特定の順序で格納されず、データ ページの並びにも特定の順序はありません。データ ページはリンク リストにリンクされません。詳細については、「ヒープ構造」を参照してください。

インデックス付きビューには、クラスタ化テーブルと同じストレージ構造があります。

ヒープまたはクラスタ化テーブルに複数のパーティションがある場合、各パーティションには、特定のパーティションの行の集合を含んだヒープまたは B ツリー構造が 1 つあります。たとえば、クラスタ化テーブルに 4 つのパーティションがある場合は、4 つの B ツリーがあります。この場合、パーティションごとに 1 つの B ツリーがあります。

非クラスタ化インデックス

非クラスタ化インデックスには、クラスタ化インデックスの B ツリーに類似した B ツリー インデックス構造があります。相違点は、非クラスタ化インデックスではデータ行の順序が影響を受けない点です。リーフ レベルにはインデックス行が格納されます。各インデックス行には、非クラスタ化キーの値、行ロケータ、および任意の付加列または非キー列が格納されます。行ロケータは、キー値を保持するデータ行を指します。詳細については、「非クラスタ化インデックスの構造」を参照してください。

XML インデックス

テーブルの各 xml 列には、1 つのプライマリ XML インデックスといくつかのセカンダリ XML インデックスを作成できます。XML インデックスは、xml データ型列内の XML バイナリ ラージ オブジェクト (BLOB) の細分化された永続化表現です。XML インデックスは内部テーブルとして格納されます。XML インデックスについての情報を表示するには、sys.xml_indexes カタログ ビューまたは sys.internal_tables カタログ ビューを使用します。

XML インデックスの詳細については、「XML データ型の列のインデックス」を参照してください。

アロケーション ユニット

アロケーション ユニットとは、ヒープまたは B ツリー内のページ集合であり、各ページ型に基づいてデータを管理するために使用されます。次の表は、テーブルまたはインデックス内のデータの管理に使用されるアロケーション ユニットの種類を示します。

アロケーション ユニットの種類

管理する対象

IN_ROW_DATA

ラージ オブジェクト (LOB) データを除くすべてのデータを格納するデータ行またはインデックス行。

ページは、データ型またはインデックス型です。

LOB_DATA

text、ntext、image、xml、varchar(max)、nvarchar(max)、varbinary(max)、または CLR ユーザー定義型 (CLR UDT) のうちの 1 つ以上のデータ型として格納されたラージ オブジェクト データ。

ページは、text 型または image 型です。

ROW_OVERFLOW_DATA

行サイズの上限である 8,060 バイトを超えている varchar 列、nvarchar 列、varbinary 列、または sql_variant 列に格納された可変長のデータ。

ページは、text 型または image 型です。

ページ型の詳細については、「ページとエクステントについて」を参照してください。

ヒープまたは B ツリーの特定のパーティション内で、各型のアロケーション ユニットは 1 つだけです。テーブルまたはインデックスのアロケーション ユニットの情報を表示するには、sys.allocation_units カタログ ビューを使用します。

IN_ROW_DATA アロケーション ユニット

テーブル (ヒープまたはクラスタ化テーブル)、インデックス、またはインデックス付きビューで使用される各パーティションには、データ ページの集合で構成された IN_ROW_DATA アロケーション ユニットが 1 つあります。このアロケーション ユニットには、別のページ集合も含まれており、テーブルまたはビューに対して定義されている各非クラスタ化インデックスおよび XML インデックスを実装できます。テーブル、インデックス、またはインデックス付きビューの各パーティション内のページ集合は、sys.system_internals_allocation_units システム ビューのページ ポインタによりアンカーが設定されます。

重要な注意事項重要

sys.system_internals_allocation_units システム ビューは MicrosoftSQL Server 内部使用専用に予約されています。将来の互換性は保証されません。

テーブル、インデックス、およびインデックス付きビューの各パーティションには、sys.system_internals_allocation_units 内にコンテナ ID (container_id) で一意に識別される行が 1 行あります。コンテナ ID は、sys.partitions カタログ ビューの partition_id と一対一でマップされています。このカタログ ビューでは、1 つのパーティションに格納された、テーブル、インデックス、またはインデックス付きビューのデータとそのパーティション内のデータの管理に使用されるアロケーション ユニットの間のリレーションシップが維持されています。

テーブル、インデックス、およびインデックス付きビューのパーティションへのページの割り当ては、IAM ページのチェーンによって管理されます。sys.system_internals_allocation_units 内の first_iam_page 列は、IN_ROW_DATA アロケーション ユニット内の、テーブル、インデックス、またはインデックス付きビューに割り当てられた領域を管理している IAM ページのチェーンで最初の IAM ページを指しています。

sys.partitions はテーブルまたはインデックス内の各パーティションの行を返します。

  • ヒープには、sys.partitions 内に index_id が 0 の行が 1 行あります。

    sys.system_internals_allocation_unitsfirst_iam_page 列は、特定のパーティション内のヒープ データ ページ集合の IAM チェーンを指します。サーバーは、相互にリンクされていないデータ ページ集合内のページを検出する際に、IAM ページを使用します。

  • テーブルまたはビューのクラスタ化インデックスは、sys.partitions 内に index_id = 1 の行を 1 行持っています。

    sys.system_internals_allocation_unitsroot_page 列は、特定のパーティション内のクラスタ化インデックス B ツリーの最上位を指します。サーバーでは、インデックス B ツリーを使用してパーティション内のデータ ページを検出します。

  • 1 つのテーブルまたはビューに対して作成された各非クラスタ化インデックスは、sys.partitions 内に index_id > 1 の行を 1 行持っています。

    sys.system_internals_allocation_unitsroot_page 列は、特定のパーティション内の非クラスタ化インデックス B ツリーの最上位を指します。

  • 1 つ以上の LOB 列がある各テーブルは、sys.partitions 内に index_id > 250 の行を 1 行持っています。

    first_iam_page 列は、LOB_DATA アロケーション ユニット内のページを管理する IAM ページのチェーンを指します。

ROW_OVERFLOW_DATA アロケーション ユニット

テーブル (ヒープまたはクラスタ化テーブル)、インデックス、またはインデックス付きビューによって使用される各パーティションには、ROW_OVERFLOW_DATA アロケーション ユニットが 1 つあります。このアロケーション ユニットでは、可変長列 (varchar、nvarchar、varbinary、または sql_variant) を含む IN_ROW_DATA アロケーション ユニット内のデータ行が、行サイズの上限である 8 KB を超えるまで、サイズがゼロ (0) のページが保持されます。サイズの上限に達すると、SQL Server により、データ行内の最大幅の列が ROW_OVERFLOW_DATA アロケーション ユニット内のページに移動されます。この行外のデータを指す 24 バイトのポインタは、元のページで維持されます。

ROW_OVERFLOW_DATA アロケーション ユニット内の Text 型または Image 型のページは、LOB_DATA アロケーション ユニット内のページと同様の方法で管理されます。つまり、Text 型または Image 型のページは IAM ページのチェーンによって管理されます。

LOB_DATA アロケーション ユニット

テーブルまたはインデックスに 1 つ以上の LOB データ型が含まれている場合、パーティション 1 つあたりに 1 つの LOB_DATA アロケーション ユニットが割り当てられて、そのデータの格納が管理されます。LOB データ型には、text、ntext、image、xml、varchar(max)、nvarchar(max)、varbinary(max)、および CLR ユーザー定義型があります。

パーティションとアロケーション ユニットの例

次の例では、LOB データが格納され、非クラスタ化インデックスがないヒープ DatabaseLog と、LOB データが格納されておらず、非クラスタ化インデックスが 1 つもないクラスタ化テーブル Currency という 2 つのテーブルのパーティションとアロケーション ユニットのデータを返します。どちらのテーブルにもパーティションが 1 つあります。

USE AdventureWorks;
GO
SELECT o.name AS table_name,p.index_id, i.name AS index_name , au.type_desc AS allocation_type, au.data_pages, partition_number
FROM sys.allocation_units AS au
    JOIN sys.partitions AS p ON au.container_id = p.partition_id
    JOIN sys.objects AS o ON p.object_id = o.object_id
    JOIN sys.indexes AS i ON p.index_id = i.index_id AND i.object_id = p.object_id
WHERE o.name = N'DatabaseLog' OR o.name = N'Currency'
ORDER BY o.name, p.index_id;

次に結果セットを示します。DatabaseLog テーブルにはデータ型のデータと Text 型または Image 型のページの両方が含まれているので、このテーブルではすべてのアロケーション ユニットが使用されます。Currency テーブルには LOB データが含まれていませんが、データ ページの管理に必要なアロケーション ユニットが含まれています。この後 Currency テーブルを LOB データ型の列を含むように変更すると、LOB データを管理するための LOB_DATA アロケーション ユニットが作成されます。

table_name  index_id index_name               allocation_type     data_pages  partition_number 
----------- -------- -----------------------  ---------------     -----------  ------------
Currency    1        PK_Currency_CurrencyCode IN_ROW_DATA         1           1
Currency    3        AK_Currency_Name         IN_ROW_DATA         1           1
DatabaseLog 0        NULL                     IN_ROW_DATA         160         1
DatabaseLog 0        NULL                     ROW_OVERFLOW_DATA   0           1
DatabaseLog 0        NULL                     LOB_DATA            49          1
(5 row(s) affected)