2列のテーブルがあります。両方の列のタイプはに設定されvarchar(38)
ます。列の1つに空の値を持つ行を作成する場合、値が空でない場合と同じストレージスペースが必要ですか?
言い換えると、MySQLは行の作成時に列のストレージスペースを(そのタイプに応じて)予約しますか?
2列のテーブルがあります。両方の列のタイプはに設定されvarchar(38)
ます。列の1つに空の値を持つ行を作成する場合、値が空でない場合と同じストレージスペースが必要ですか?
言い換えると、MySQLは行の作成時に列のストレージスペースを(そのタイプに応じて)予約しますか?
回答:
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
、列のストレージの値が占めるものを以下に示します
ここで、最初のポイントがもたらしたもののため、CHARとVARCHARのどちらを使用するかを決定する必要があります
NULL値用の固定スペースを予約すると、インデックスページの断片化を引き起こすことなく、所定の場所でNULLから非NULL値への列の更新が可能になります。
これにより、NULL以外のデータが格納されると、行の断片化が発生しなくなります。これはMyISAMに関して以前に説明したことです。古い投稿を参照してください。固定サイズのフィールドでCHARとVARCHARを使用するとパフォーマンスにどのような影響がありますか?。
SELECT
一時テーブルを作成する必要があるコンプレックスがある場合、過剰割り当てのペナルティが発生します。可能であれば、を使用し、tmpテーブル用にMEMORY
変換VARCHAR
しCHAR
ます。今VARCHAR(100)
固定100(または300)を取りバイト、それによっておそらくクエリを遅くします。
varchar列に定義する長さに関係なく、空の列で使用される記憶領域は同じになります。
これは、varchar列が使用するスペースのみを対象とし、行、そのインデックス、プライマリキー、およびその他の列が使用する合計ストレージスペースは考慮しません。
ypercubeが彼のコメントで言及しているように、少なくとも1つのNULL入力可能列が存在する場合、行ストレージ全体に関して追加の考慮事項があります。
レコードヘッダーの可変長部分には、NULL列を示すためのビットベクトルが含まれています。NULLにできる9〜15の列がある場合、ビットベクトルは2バイトを使用します。)
...
ヘッダーの可変長部分には、可変長列の長さも含まれます。各長さは、列の最大長に応じて1バイトまたは2バイトかかります。インデックス内のすべての列がNULLでなく、固定長である場合、レコードヘッダーには可変長部分がありません
はい、使用するストレージスペースは、選択したタイプ、固定または可変、照合、エンジンなどの他の要因に基づいて変化します。
MySQLはここでデータストレージの最適化に関する推奨事項を作成します:データサイズの最適化
更新
varcharとそれについてのもう1つの考慮事項とそれがメモリです。MySQLでは、可変長列のサイズをできるだけ制限することが重要です。カラムが可変で、使用されるストレージスペースが可変であっても、MySQLは値を格納するためにメモリを固定チャンクで割り当てます。たとえば、varchar(200)はvarchar(5)よりも多くのメモリを使用します。これはストレージ領域の問題ではありませんが、列を定義するときに考慮すべき事項です。
CHARACTER SET
latin1またはasciiを想定しています。UTF8の場合は、ストレージのための必須CHAR(4)
12です