MySQLで、nullはパフォーマンスとストレージ(スペース)をどのように賢くしますか?
例えば:
TINYINT:1バイトTINYINT w/NULL 1バイト+どういうわけかNULLを格納しますか?
使用するストレージエンジンによって異なります。
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がパフォーマンスに与える影響を心配することは、マイクロ最適化の領域です。あなたは、他の場所に、お金に大きな価値を与える領域に注意を向けるべきです。たとえば、適切に選択されたインデックスを追加したり、データベースキャッシュの割り当てを増やしたりします。
ビルの答えは良いですが、少し時代遅れです。 NULLを保存するための1バイトまたは2バイトの使用は、InnoDB REDUNDANT行形式にonlyを適用します。 MySQL 5.0.3 InnoDBは[〜#〜] compact [〜#〜]を使用するため、1ビットのみを使用してNULLを格納します(もちろん1バイトが最小です)、したがって:
NULLに必要なスペース=CEILING(N/8)bytesここで、Nは行内のNULL列の数です。
コンパクトvs冗長性に関するMySQLの公式サイトによると:
コンパクト行形式では、一部の操作でCPU使用量が増加する代わりに、行の記憶領域が約20%減少します。ワークロードがキャッシュヒット率とディスク速度によって制限される一般的なワークロードである場合、コンパクトフォーマットの方が高速になる可能性があります。
あなたはここで節約を見始めます:
一方、空の文字列またはゼロではNULLを使用することをお勧めします。これらは、より整理され、移植性があり、必要なスペースが少ないためです。パフォーマンスを向上させてスペースを節約するには、奇妙なトリックの代わりに適切なデータ型、インデックス、クエリを使用することに焦点を合わせます。
詳細: https://dev.mysql.com/doc/refman/5.7/en/innodb-physical-record.html
これらのMySQLのヒント を追加しますが、Bill Karwinに同意します。 11番はこれに特に対処しています。
まず、空の文字列値とNULL値(INTフィールドの場合:0とNULL)に違いがあるかどうかを自問します。両方を持つ理由がない場合は、NULLフィールドは必要ありません。 (OracleはNULLと空の文字列を同じものとみなすことをご存知ですか?)
NULL列には追加のスペースが必要であり、比較ステートメントが複雑になる可能性があります。できる限り避けてください。ただし、NULL値を使用する非常に具体的な理由がある人がいるかもしれませんが、これは必ずしも悪いことではありません。
一方、多くの行を持たないテーブルでは、まだNULLを使用しています。これは、主にNOT NULLと言うロジックが好きだからです。
Update後でこれを再考しますが、個人的にはデータベースでNULLの代わりに0を使用したくないと付け加えます。 。注意を怠ると、アプリケーションで多くの誤検知が発生する可能性があります。
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を検索できます