行の圧縮の実装

適用対象:SQL ServerAzure SQL DatabaseAzure SQL Managed Instance

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

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

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

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

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

Note

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

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

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

データ型 ストレージへの影響の有無 説明
tinyint いいえ 1 バイトの最小ストレージが必要です。
smallint はい 値が 1 バイトに収まる場合は、1 バイトしか使用されません。
int はい 必要なバイトのみを使用します。 たとえば、値を 1 バイトに格納できる場合、ストレージでは 1 バイトしか消費されません。
bigint はい 必要なバイトのみを使用します。 たとえば、値を 1 バイトに格納できる場合、ストレージでは 1 バイトしか消費されません。
decimal はい 指定された有効桁数に関係なく、必要なバイトのみが使用されます。 たとえば、値を 3 バイトに格納できる場合、ストレージでは 3 バイトしか消費されません。 ストレージの占有領域は、vardecimal の保存形式とまったく同じです。
numeric はい 指定された有効桁数に関係なく、必要なバイトのみが使用されます。 たとえば、値を 3 バイトに格納できる場合、ストレージでは 3 バイトしか消費されません。 ストレージの占有領域は、vardecimal の保存形式とまったく同じです。
bit はい メタデータのオーバーヘッドにより、これは 4 ビットになります。
smallmoney はい 4 バイト整数を使用して、整数データ表現を使用します。 通貨値には 10,000 が乗算され、その結果の整数値は、小数点以下桁数をすべて削除して格納されます。 この型では、整数型と同様にストレージを最適化します。
money はい 8 バイト整数を使用して、整数データ表現を使用します。 通貨値には 10,000 が乗算され、その結果の整数値は、小数点以下桁数をすべて削除して格納されます。 この型の範囲は、 smallmoneyより大きくなります。 この型では、整数型と同様にストレージを最適化します。
float はい 0 が設定された最下位バイトは格納されません。 float の圧縮は、多くの場合、仮数の整数部分に適用されます。
実質 はい 0 が設定された最下位バイトは格納されません。 real の圧縮は、多くの場合、仮数の整数部分に適用されます。
smalldatetime いいえ 2 つの 2 バイト整数による整数データ表現を使用します。これは 1900-01-01 以降の日数です。 smalldatetime の日付部分については、行を圧縮しても利点はありません。

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

smalldatetime が日付を表すためだけに使用される場合 (一般的なケース)、時刻は 0.0 になります。 圧縮により、時刻は行の圧縮の最上位バイト形式で格納されるため、2 バイト節約されます。
datetime はい 2 つの 4 バイト整数を使用して、整数データ表現を使用します。 1900-01-01 を基準日とした日数を整数値で表します。 最初の 2 バイトで、2079 年まで表すことができます。 その時点までは、圧縮により常に 2 バイト節約されます。 各整数値は 3.33 ミリ秒を表します。 圧縮により、最初の 5 分で最初の 2 バイトが使用され、午後 4 時を過ぎると 4 番目のバイトが必要になります。 したがって、午後 4 時を過ぎると、圧縮しても 1 バイトしか節約されません。 datetime が他の整数と同様に圧縮されると、その日付では 2 バイト節約されます。
date いいえ 3 バイトを使用して、整数データ表現を使用します。 これは、0001-01-01 からの日付を表します。 現代の日付の場合、行の圧縮により 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 バイトで日付を表します。 時刻で使用されるバイト数は、指定する時刻の有効桁数によって異なります。

0001-01-01 から経過した日数を、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 1 末尾の埋め込み文字が削除されます。 データベース エンジンでは、使用される照合順序に関係なく、同じ埋め込み文字が挿入されます。
nvarchar いいえ 1 影響しません。
ntext いいえ 影響しません。
[バイナリ] はい 末尾の 0 が削除されます。
varbinary いいえ 影響しません。
image いいえ 影響しません。
cursor いいえ 影響しません。
timestamp / rowversion はい 8 バイトを使用して、整数データ表現を使用します。 データベースごとに保持されるタイムスタンプ カウンターがあり、その値は 0 から始まります。 これは、その他の整数値と同様に圧縮できます。
sql_variant いいえ 影響しません。
uniqueidentifier いいえ 影響しません。
テーブル いいえ 影響しません。
xml いいえ 2 影響しません。
ユーザー定義データ型 いいえ これは、内部では varbinaryとして表されます。
FILESTREAM いいえ これは、内部では varbinaryとして表されます。

1 Unicode 圧縮では、固定長の nchar データ型および nvarchar データ型がサポートされます。 行外または nvarchar(max) 列に格納されるデータ値は圧縮されません。 行内に格納される場合も、nvarchar(max) データでは Unicode 圧縮がサポートされません。

2 データ圧縮を有効にしても、行外のデータは圧縮されません。 たとえば、8060 バイトを超える XML レコードには、行外のページが使用され、これは圧縮されません。