バージョン:mysql5
データ型 :InnoDB
カラムを追加する前と後で、
InnoDBの空き容量を比較したのですが、
ほぼ変化がありませんでした。
追加したテーブルは800万レコード程度あります。
SQLは下記のような形です。
alter table hogehoge add col varchar(255)
InnoDBの空き領域に関しては、
「show table status」で調べました。
単純にカラム追加で新しく領域を確保して、
InnoDBの空き容量は減ると想定したのですが、
こちらの現象はどういった理由によるものでしょうか。
よろしくお願いします。
SHOW TABLE STATUS のどのデータを見ていますか?
もし Data_free だとすると、これは使用されていないエクステントのサイズを示しています。実際には、ページ単位の空き領域の合算値を示すこととなり、フラグメンテーションを起こしているかどうかの指標になります。
つまり、alter add したばかりであれば、エクステントは増えませんから、Data_free の値も変わりません。
InnoDB は内部的に固定長フォーマットの CHAR(10) のような固定長文字カラムを格納します。
InnoDB は VARCHAR カラムから後続領域を切り捨てます。
何もデータが入っていないVARCHAR形のフィールドはデータ量ゼロ。
ただし、データ量はゼロでも管理するために
SQL NULL 値はレコード ディレクトリ内で1か2バイトを蓄えておきます。
それ以外に、SQL NULL 値は可変長カラム内に格納されるとレコードのデータ部分にゼロ バイトを蓄えます。
それは固定長カラム内でレコードのデータ部分内にカラムの固定長を蓄えます。
NULL 値に固定領域を蓄える目的は、そうする事でインデックス ページの崩壊を起こさずに
NULL からのカラムを非 NULL 値に、更新する事ができるという事です。
や
レコードには、そのレコードの各フィールドへのポインタも含まれます。
レコード内のフィールド長の合計が128バイト未満の場合はポインタが1バイト、
128バイト以上の場合はポインタが2バイトになります。
これらのポインタの配列はレコード ディレクトリと呼ばれます。
これらのポインタが指し示すエリアはレコードのデータ部分と呼ばれます。
などがありますので
800万レコードもあれば数十から数百MBの増加があるはずです。
InnoDB の場合、DBの実体は、ある一定の初期サイズのファイルになっており、データ容量がこれを超えると自動的に一定の容量だけファイルサイズを拡張していく(エクステント)仕組みになっています。詳しくは「InnoDB 起動オプション」(MySQL公式マニュアル)を参考にしてください。
Comment に表示される "InnoDB free" は、確保されたファイルサイズの残容量を示します。
varchar カラムは可変長であるため、定義時に確保されるのは、データ長を格納する領域(255以下なら1バイト、256以上なら2バイト)だけです。
もし800万レコードの varchar(255) を add したとしても、それによって消費される容量は、8,000,000×1=7.6Mバイト程度に過ぎません。
この程度の増分では、過去にパージされなかったエクステントに吸収されてしまい、free area として表れなかったのではないかと推測します。
Commentの項目の「InnoDB free」の値を見ています。
Data_freeではないです。
よろしくお願いします。