行の圧縮の実装

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

圧縮を有効にすると、データ型に関連付けられているデータの物理的なストレージ形式が変更されるだけで、その構文やセマンティクスは変更されません。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

あり

圧縮後のテキストのサイズが現在のテキストのサイズより小さくなる場合、テキストは、Standard Compression Scheme for Unicode (SCSU) アルゴリズムを使用して圧縮されます。

nvarchar

あり

圧縮後のテキストのサイズが現在のテキストのサイズより小さくなる場合、テキストは、Standard Compression Scheme for Unicode (SCSU) アルゴリズムを使用して圧縮されます。

注意
nvarchar(max) では、圧縮はサポートされません。

ntext

なし

影響しません。

binary

あり

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

varbinary

なし

影響しません。

image

なし

影響しません。

cursor

なし

影響しません。

timestamp / rowversion

あり

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

sql_variant

なし

影響しません。

uniqueidentifier

なし

影響しません。

table

なし

影響しません。

xml

なし

影響しません。

ユーザー定義型

なし

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

FILESTREAM

なし

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