Microsoft SQL Serverでは、データ(インデックスを含む)は1つ以上の8k(8192バイト)の「ページ」に格納されます。さまざまな状況(データ、LOB、インデックス、AllocationMapなど)を処理するために使用できるさまざまなタイプのページがあります。各ページには、そのページとそのページの内容に関するメタデータであるヘッダーがあります。
ほとんどのデータは行自体に格納され、これらの行の1つ以上が「行内データ」のページに格納されます。行ヘッダーが占めるスペースのため、(「行内」データの場合)行の最大値は8060バイトです。
ただし、すべてのデータが行に格納されるわけではありません。特定のデータ型では、ポインタを「行内」データに残したまま、データを実際に「LOBデータ」ページに格納できます。
-
誰も使用してはならないレガシー/非推奨のLOBタイプ(
TEXT
、NTEXT
、およびIMAGE
)、デフォルトでは、常にデータをLOBページに格納し、常にそのLOBページへの16バイトのポインタを使用します。 -
新しいLOBタイプ(
VARCHAR(MAX)
、NVARCHAR(MAX)
、VARBINARY(MAX)
、およびXML
)デフォルトでは、データが収まる場合は、データを行に直接収まろうとします。それ以外の場合は、データをLOBページに格納し、24〜72バイトのポインターを使用します(LOBデータのサイズによって異なります)。
これは、最大78 GB + 4バイトを格納する方法です(INT
を忘れないでください) 単一行の主キー;-):最大行サイズは940バイト((39 * 24)+ 4)から2812バイト((39 * 72)+ 4)の間になります。しかし、繰り返しになりますが、これは最大範囲にすぎません。 39個のVARCHAR(MAX)
のそれぞれのデータの場合 フィールドがわずか10バイトの場合、すべてのデータが行に格納され、行サイズは394バイト((39 * 10)+ 4)になります。
可変長フィールドが非常に多い場合(MAXであるかどうかに関係なく)、将来の行のサイズを見積もる唯一の方法は、このテーブルに格納するデータについてよく理解することです。ただし、すべて、またはほとんどの場合、MAXデータ型を含むテーブルは、このテーブルに何が格納されるのかを実際に誰も知らないことを意味します。
これらの線に沿って、これは恐ろしくモデル化されたテーブル/ MAXデータ型フィールドの恐ろしい使用であり、リファクタリングする必要があることを指摘しておく必要があります。
データページの構造の詳細については、次のDBA.StackExchangeの質問に対する私の回答を参照してください。
sys.allocation_unitsのテーブルサイズと一致しないDATALENGTHの合計