web-dev-qa-db-ja.com

MySQLのNULL(パフォーマンスとストレージ)

MySQLで、nullはパフォーマンスとストレージ(スペース)をどのように賢くしますか?

例えば:

TINYINT:1バイトTINYINT w/NULL 1バイト+どういうわけかNULLを格納しますか?

68
Steve

使用するストレージエンジンによって異なります。

MyISAM形式では、各行ヘッダーには、NULL状態をエンコードするために各列に1ビットのビットフィールドが含まれています。 NULLの列は依然としてスペースを占有するため、NULLがストレージを削減することはありません。 https://dev.mysql.com/doc/internals/en/myisam-introduction.html を参照してください

InnoDBでは、各列の行ヘッダーに「フィールド開始オフセット」があり、これは列ごとに1または2バイトです。列がNULLの場合、そのフィールド開始オフセットの上位ビットはオンです。その場合、列をまったく保存する必要はありません。したがって、多くのNULLがある場合、ストレージを大幅に削減する必要があります。 https://dev.mysql.com/doc/internals/en/innodb-field-contents.html を参照してください

編集:

NULLビットは行ヘッダーの一部であり、追加することは選択しません。

NULLがパフォーマンスを向上させると想像できる唯一の方法は、InnoDBでは、行にNULLが含まれている場合、データのページがより多くの行に適合する可能性があるということです。したがって、InnoDBバッファーの方が効果的です。

しかし、これが実際にパフォーマンス上の大きな利点を提供する場合、私は非常に驚くでしょう。 NULLがパフォーマンスに与える影響を心配することは、マイクロ最適化の領域です。あなたは、他の場所に、お金に大きな価値を与える領域に注意を向けるべきです。たとえば、適切に選択されたインデックスを追加したり、データベースキャッシュの割り当てを増やしたりします。

93
Bill Karwin

ビルの答えは良いですが、少し時代遅れです。 NULLを保存するための1バイトまたは2バイトの使用は、InnoDB REDUNDANT行形式にonlyを適用します。 MySQL 5.0.3 InnoDBは[〜#〜] compact [〜#〜]を使用するため、1ビットのみを使用してNULLを格納します(もちろん1バイトが最小です)、したがって:

NULLに必要なスペース=CEILING(N/8)bytesここで、Nは行内のNULL列の数です。

  • 0 NULLS = 0バイト
  • 1-8 NULLS = 1バイト
  • 9-16 NULLS = 2バイト
  • 17-24 NULLS = 3バイト
  • 等...

コンパクトvs冗長性に関するMySQLの公式サイトによると:

コンパクト行形式では、一部の操作でCPU使用量が増加する代わりに、行の記憶領域が約20%減少します。ワークロードがキャッシュヒット率とディスク速度によって制限される一般的なワークロードである場合、コンパクトフォーマットの方が高速になる可能性があります。

空の文字列またはゼロよりもNULLSを使用する利点:

  • 1 NULLには1バイトが必要です
  • 1つの空の文字列には1バイトが必要です(VARCHARと仮定)
  • 1ゼロには4バイトが必要です(INTと仮定)

あなたはここで節約を見始めます:

  • 8 NULLは1バイトを必要とします
  • 8つの空の文字列には8バイトが必要です
  • 8ゼロには32バイトが必要

一方、空の文字列またはゼロではNULLを使用することをお勧めします。これらは、より整理され、移植性があり、必要なスペースが少ないためです。パフォーマンスを向上させてスペースを節約するには、奇妙なトリックの代わりに適切なデータ型、インデックス、クエリを使用することに焦点を合わせます。

詳細: https://dev.mysql.com/doc/refman/5.7/en/innodb-physical-record.html

31
Arian Acosta

これらのMySQLのヒント を追加しますが、Bill Karwinに同意します。 11番はこれに特に対処しています。

まず、空の文字列値とNULL値(INTフィールドの場合:0とNULL)に違いがあるかどうかを自問します。両方を持つ理由がない場合は、NULLフィールドは必要ありません。 (OracleはNULLと空の文字列を同じものとみなすことをご存知ですか?)

NULL列には追加のスペースが必要であり、比較ステートメントが複雑になる可能性があります。できる限り避けてください。ただし、NULL値を使用する非常に具体的な理由がある人がいるかもしれませんが、これは必ずしも悪いことではありません。

一方、多くの行を持たないテーブルでは、まだNULLを使用しています。これは、主にNOT NULLと言うロジックが好きだからです。

Update後でこれを再考しますが、個人的にはデータベースでNULLの代わりに0を使用したくないと付け加えます。 。注意を怠ると、アプリケーションで多くの誤検知が発生する可能性があります。

6

dev.mysql.com/doc/refman/5.0/en/is-null-optimization.html

MySQLは、col_name = constant_valueに使用できるのと同じ最適化をcol_name IS NULLで実行できます。たとえば、MySQLはインデックスと範囲を使用してIS NULLでNULLを検索できます

1
Chu Khanh Van