82

MySQLでnullはパフォーマンスとストレージ(スペース)に関して正確に何をしますか?

例えば:

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

4

4 に答える 4

106

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

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 がパフォーマンスに与える影響について心配することは、マイクロ最適化の領域にあります。他の場所、つまり投資に見合う効果が大きい分野に注意を向けるべきです。たとえば、適切に選択されたインデックスを追加したり、データベース キャッシュの割り当てを増やしたりします。

于 2008-10-23T18:41:38.743 に答える
47

ビルの答えは良いですが、少し時代遅れです。NULL を格納するための 1 バイトまたは 2 バイトの使用は、InnoDB REDUNDANT 行フォーマットにのみ適用されます。MySQL 5.0.3 以降、InnoDB はNULL を格納するために 1 ビットのみを使用するCOMPACT行フォーマットを使用します (もちろん、1 バイトが最小です)。

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

  • 0 NULLS = 0 バイト
  • 1 ~ 8 個のヌル = 1 バイト
  • 9 ~ 16 個のヌル = 2 バイト
  • 17 ~ 24 個のヌル = 3 バイト
  • 等...

COMPACT vs REDUNDANT に関する MySQL の公式サイトによると、次のようになります。

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

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

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

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

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

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

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

于 2015-08-18T04:52:00.047 に答える
7

これらの MySQL のヒントを追加しますが、Bill Karwin に同意します。11 番は具体的に次のように述べています。

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

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

一方で、主に NOT NULL と言う論理が好きなので、大量の行を持たないテーブルでは今でも null を使用しています。

更新 これを後で再検討すると、個人的にはデータベースで NULL の代わりに 0 を使用するのは好きではなく、お勧めしません。注意しないと、アプリケーションで多くの誤検知が発生する可能性があります。

于 2015-03-08T22:58:36.023 に答える
1

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 を検索できます。

于 2013-05-19T17:30:42.107 に答える