空の列値は、入力された列値と同じストレージスペースを占有しますか?


15

2列のテーブルがあります。両方の列のタイプはに設定されvarchar(38)ます。列の1つに空の値を持つ行を作成する場合、値が空でない場合と同じストレージスペースが必要ですか?

言い換えると、MySQLは行の作成時に列のストレージスペースを(そのタイプに応じて)予約しますか?

回答:


11

Innodb物理行構造から、REDUNDANT ROW_FORMATの下の箇条書き#7

SQL NULL値は、レコードディレクトリに1バイトまたは2バイトを予約します。それに加えて、SQL NULL値は、可変長列に格納されている場合、レコードのデータ部分にゼロバイトを予約します固定長の列は、レコードのデータ部分にカラムの固定長を留保します。NULL値用の固定スペースを予約すると、インデックスページの断片化を引き起こすことなく、所定の場所でNULLから非NULL値への列の更新が可能になります。

Innodb物理行構造から、COMPACT ROW_FORMATの下の箇条書き#2

レコードヘッダーの可変長部分には、NULL列を示すためのビットベクトルが含まれています。NULLにできるインデックスの列の数がNの場合、ビットベクトルはCEILING(N / 8)バイトを占有します。(たとえば、NULLにできる9〜15列がある場合、ビットベクトルは2バイトを使用します。) NULLの列は、このベクトルのビット以外のスペースを占有しません。ヘッダーの可変長部分には、可変長列の長さも含まれます。各長さは、列の最大長に応じて1バイトまたは2バイトかかります。インデックス内のすべての列がNULLでなく、固定長である場合、レコードヘッダーには可変長部分がありません。

これらの箇条書きに基づいてNULL、列のストレージの値が占めるものを以下に示します

  • 可変長:NULL値行自体のストレージ占有しません
  • 固定長:予約済みスペースを占有します

ここで、最初のポイントがもたらしたもののため、CHARとVARCHARのどちらを使用するかを決定する必要があります

NULL値用の固定スペースを予約すると、インデックスページの断片化を引き起こすことなく、所定の場所でNULLから非NULL値への列の更新が可能になります。

これにより、NULL以外のデータが格納されると、行の断片化が発生しなくなります。これはMyISAMに関して以前に説明したことです。古い投稿を参照してください。固定サイズのフィールドでCHARとVARCHARを使用するとパフォーマンスにどのような影響がありますか?


こんにちは、ロランド、言及し忘れた別の項目がありました。varchar(5)とvarchar(100)の型宣言のメモリ割り当ての違いです。または実際には、過剰割り当てによって発生するペナルティ。
クレイグエフレイン

@CraigEfreinあなたは間違いなくあなたの答えにメモリ割り当てを追加する必要があります。(ちなみに私はすでにあなたの答えをupvoted)
RolandoMySQLDBA

1
SELECT一時テーブルを作成する必要があるコンプレックスがある場合、過剰割り当てのペナルティが発生します。可能であれば、を使用し、tmpテーブル用にMEMORY変換VARCHARCHARます。今VARCHAR(100)固定100(または300)を取りバイト、それによっておそらくクエリを遅くします。
リックジェームズ

@ RolandoMySQLDBA、Mysql 5.7 DYNAMICおよびCOMPACT行フォーマットに適用可能な回答で説明されている動作です。
ディネシュクマール

@DineshKumarこれらの段落はまだ5.7 / 8.0のドキュメントにあります。DYNAMIC については、dev.mysql.com / doc / refman / 5.7 / en / innodb-row-format-dynamic.htmlを参照してください。
RolandoMySQLDBA

8

varchar列に定義する長さに関係なく、空の列で使用される記憶領域は同じになります。

CHARおよびVARCHARタイプ

ここに画像の説明を入力してください

これは、varchar列が使用するスペースのみを対象とし、行、そのインデックス、プライマリキー、およびその他の列が使用する合計ストレージスペースは考慮しません。

ypercubeが彼のコメントで言及しているように、少なくとも1つのNULL入力可能列が存在する場合、行ストレージ全体に関して追加の考慮事項があります。

Innodbの物理的な行構造

レコードヘッダーの可変長部分には、NULL列を示すためのビットベクトルが含まれています。NULLにできる9〜15の列がある場合、ビットベクトルは2バイトを使用します。)

...

ヘッダーの可変長部分には、可変長列の長さも含まれます。各長さは、列の最大長に応じて1バイトまたは2バイトかかります。インデックス内のすべての列がNULLでなく、固定長である場合、レコードヘッダーには可変長部分がありません

はい、使用するストレージスペースは、選択したタイプ、固定または可変、照合、エンジンなどの他の要因に基づいて変化します。

MySQLはここでデータストレージの最適化に関する推奨事項を作成します:データサイズの最適化

更新

varcharとそれについてのもう1つの考慮事項とそれがメモリです。MySQLでは、可変長列のサイズをできるだけ制限することが重要です。カラムが可変で、使用されるストレージスペースが可変であっても、MySQLは値を格納するためにメモリを固定チャンクで割り当てます。たとえば、varchar(200)はvarchar(5)よりも多くのメモリを使用します。これはストレージ領域の問題ではありませんが、列を定義するときに考慮すべき事項です。


上記の数値は、CHARACTER SETlatin1またはasciiを想定しています。UTF8の場合は、ストレージのための必須CHAR(4)12です
リック・ジェームス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.