行の圧縮の実装

このトピックでは、データベース エンジンに実装されている行の圧縮方法の概要を説明します。この概要では、データに必要なストレージ領域の計画に役立つ基本的な情報を提供します。

圧縮を有効にすると、データ型に関連付けられているデータの物理的なストレージ形式が変更されるだけで、その構文やセマンティクスは変更されません。1 つ以上のテーブルで圧縮を有効にしても、アプリケーションの変更は必要ありません。新しいレコードのストレージ形式には、主に、次の変更点があります。

  • レコードに関連付けられているメタデータのオーバーヘッドが減少します。このメタデータは、列、列の長さ、およびオフセットに関する情報です。メタデータのオーバーヘッドは、古いストレージ形式より大きい場合もあります。

  • 数値型 (integer、decimal、float など) および数値に基づく型 (datetime、money など) には、可変長のストレージ形式を使用します。

  • 空白文字を格納せずに可変長の形式を使用することで、固定文字列を格納します。

注意注意

すべてのデータ型で値が NULL および 0 の場合は、最適化されているため、バイトは消費されません。

行の圧縮によるストレージへの影響

次の表では、行の圧縮が SQL Server の既存の型に与える影響について説明します。この表では、ページの圧縮を使用して実現可能な節約は示されていません。

データ型

ストレージへの影響の有無

説明

tinyint

なし

1 バイトの最小ストレージが必要です。

smallint

あり

値が 1 バイトに収まる場合は、1 バイトしか使用されません。

int

あり

必要なバイトのみを使用します。たとえば、値を 1 バイトに格納できる場合、ストレージでは 1 バイトしか消費されません。

bigint

あり

必要なバイトのみを使用します。たとえば、値を 1 バイトに格納できる場合、ストレージでは 1 バイトしか消費されません。

decimal

あり

このストレージは、vardecimal ストレージ形式とまったく同じです。詳細については、「decimal データの可変長での格納」を参照してください。

numeric

あり

このストレージは、vardecimal ストレージ形式とまったく同じです。詳細については、「decimal データの可変長での格納」を参照してください。

bit

あり

メタデータのオーバーヘッドにより、これは 4 ビットになります。

smallmoney

あり

4 バイト整数を使用して、整数データ表現を使用します。通貨値には 10,000 が乗算され、その結果の整数値は、小数点以下桁数をすべて削除して格納されます。この型では、整数型と同様にストレージを最適化します。

money

あり

8 バイト整数を使用して、整数データ表現を使用します。通貨値には 10,000 が乗算され、その結果の整数値は、小数点以下桁数をすべて削除して格納されます。この型の範囲は、smallmoney より大きくなります。この型では、整数型と同様にストレージを最適化します。

float

あり

0 が設定された最下位バイトは格納されません。float の圧縮は、多くの場合、仮数の整数部分に適用されます。

real

あり

0 が設定された最下位バイトは格納されません。real の圧縮は、多くの場合、仮数の整数部分に適用されます。

smalldatetime

なし

2 つの 2 バイト整数を使用して、整数データ表現を使用します。日付では、2 バイトが使用されます。これは 1901 年 1 月 1 日から経過した日数で、1902 年以降は 2 バイト必要になります。したがって、その後は節約されません。

時刻は、午前 0 時から経過した分数です。午前 4 時を少し過ぎた時点から、時刻の値に 2 番目のバイトが使用されます。

smalldatetime が日付を表すためだけに使用される場合 (一般的なケース)、時刻は 0.0 になります。圧縮により、時刻は行の圧縮の最上位バイト形式で格納されるため、2 バイト節約されます。

datetime

あり

2 つの 4 バイト整数を使用して、整数データ表現を使用します。1900 年 1 月 1 日を基準日とした日数を整数値で表します。最初の 2 バイトで、2079 年まで表すことができます。その時点までは、圧縮により常に 2 バイト節約されます。各整数値は 3.33 ミリ秒を表します。圧縮により、最初の 5 分で最初の 2 バイトが使用され、午後 4 時を過ぎると 4 番目のバイトが必要になります。したがって、午後 4 時を過ぎると、圧縮しても 1 バイトしか節約されません。datetime が他の整数と同様に圧縮されると、その日付では 2 バイト節約されます。

date

なし

3 バイトを使用して、整数データ表現を使用します。これは、西暦 1 年 1 月 1 日からの日付を表します。現代の日付の場合、行の圧縮により 3 バイトすべてが使用されます。この場合は、節約が実現しません。

time

なし

3 ~ 6 バイトを使用して、整数データ表現を使用します。3 ~ 6 バイトを使用する、0 ~ 9 で始まるさまざまな有効桁数があります。圧縮された領域は、次のように使用されます。

  • 有効桁数 = 0、バイト数 = 3。各整数値は 1 秒を表します。圧縮により、2 バイトを使用して午後 6 時までを表し、1 バイト節約できる可能性があります。

  • 有効桁数 = 1、バイト数 = 3。各整数値は 1/10 秒を表します。圧縮では、午前 2 時の前に 3 番目のバイトを使用します。その結果、ほとんど節約されません。

  • 有効桁数 = 2、バイト数 = 3。上記の場合と同様に、節約できる可能性はほとんどありません。

  • 有効桁数 = 3、バイト数 = 4。最初の 3 バイトが午前 5 時までに使用されるため、ほとんど節約できません。

  • 有効桁数 = 4、バイト数 = 4。最初の 3 バイトが最初の 27 秒で使用されます。節約される見込みはありません。

  • 有効桁数 = 5、バイト数 = 5。5 番目のバイトが正午以降に使用されます。

  • 有効桁数 = 6 および 7、バイト数 = 5。節約は実現しません。

  • 有効桁数 = 8、バイト数 = 6。午前 3 時を過ぎると、6 番目のバイトが使用されます。

行の圧縮でストレージに変更はありません。全体的に、time データ型を圧縮しても、ほとんど節約を見込むことはできません。

datetime2

あり

6 ~ 9 バイトを使用して、整数データ表現を使用します。最初の 4 バイトで日付を表します。時刻で使用されるバイト数は、指定する時刻の有効桁数によって異なります。

西暦 1 年 1 月 1 日から経過した日数を、9999 年 12 月 31 日を上限として整数値で表します。2005 年の日付を表すには、圧縮では 3 バイトが使用されます。

さまざまな時刻の有効桁数には 2 ~ 4 バイトが必要となるため、時刻に関して節約されることはありません。したがって、1 秒の時刻の有効桁数の場合、圧縮では時刻に 2 バイトが使用されます (255 秒を過ぎると 2 番目のバイトが使用されます)。

datetimeoffset

あり

2 バイトのタイム ゾーンの形式 (HH:MM) があることを除いて、datetime2 と似ています。

datetime2 と同様、圧縮により 2 バイト節約できます。

タイム ゾーンの値では、ほとんどの場合、MM 値が 0 になります。したがって、圧縮によって 1 バイト節約できる可能性があります。

行の圧縮でストレージに変更はありません。

char

あり

末尾の埋め込み文字が削除されます。データベース エンジンでは、使用される照合順序に関係なく、同じ埋め込み文字が挿入されることに注意してください。

varchar

なし

影響しません。

text

なし

影響しません。

nchar

あり

末尾の埋め込み文字が削除されます。データベース エンジンでは、使用される照合順序に関係なく、同じ埋め込み文字が挿入されることに注意してください。

nvarchar

なし

影響しません。

ntext

なし

影響しません。

binary

あり

末尾の 0 が削除されます。

varbinary

なし

影響しません。

image

なし

影響しません。

cursor

なし

影響しません。

timestamp / rowversion

あり

8 バイトを使用して、整数データ表現を使用します。データベースごとに保持されるタイムスタンプ カウンタがあり、その値は 0 から始まります。これは、その他の整数値と同様に圧縮できます。

sql_variant

なし

影響しません。

uniqueidentifier

なし

影響しません。

table

なし

影響しません。

xml

なし

影響しません。

ユーザー定義型

なし

これは、内部では varbinary として表されます。

FILESTREAM

なし

これは、内部では varbinary として表されます。