質問: MySQLでサイトへのアクセスログを取るテーブルを作りました。 ここに実際のログデータが入ると、なぜかオーバーヘッドが発生します。 phpMyAdminでの表示は以下の通りです。 > > ディスク使用量 > > 種別 使用量 > > データ 1,552.0 KiB > > インデックス 0 バイト > > オーバーヘッド 4,096.0 KiB > > 実効 -2,605,056 バイト > > 合計 1,552.0 KiB > > > 「実効」がマイナス値というのも理解不能です。 テーブルの構造は以下の通りです。 ``` -- サーバのバージョン: 5.5.45 -- PHP のバージョン: 5.3.3 CREATE TABLE IF NOT EXISTS `log` ( `no` int(11) unsigned NOT NULL AUTO_INCREMENT, `uri` varchar(50) NOT NULL, `ip` varchar(48) NOT NULL, `ua` varchar(300) NOT NULL, `create` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `ref` varchar(100) NOT NULL, PRIMARY KEY (`no`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=3602 ; ``` 同じDB内の他のテーブルには問題なく、このlogテーブルだけオーバーヘッドが発生します。 何が原因だと考えられるでしょうか?
回答: なんか軽い気持ちでぐぐったら中々コレっていうのにヒットしなくて苦戦しました。笑 StackOverflow - How do I reduce MySQL's overhead as displayed in phpMyAdmin? PHPMyAdminで表示されるオーバヘッドは、`SHOW TABLE STATUS`の`Data_free`カラムから得られる情報を元に計算されています。このことはMySQLのドキュメントに明記されています: `Data_free`:確保されたが未使用のバイト数 > > Beginning with MySQL 5.1.24, this information is also shown for InnoDB tables (previously, it was in the Comment value). InnoDB tables report the free space of the tablespace to which the table belongs. For a table located in the shared tablespace, this is the free space of the shared tablespace. If you are using multiple tablespaces and the table has its own tablespace, the free space is for only that table. Free space means the number of completely free 1MB extents minus a safety margin. Even if free space displays as 0, it may be possible to insert rows as long as new extents need not be allocated. > > > この記述の中で重要なのは「InnoDbテーブルは所属しているテーブルスペースの空きスペースを表示します。共有テーブルスペースに作られたテーブルにとっては、これは共有テーブルスペースの空きスペースです。」という部分です。普通のInnoDbの設定では(`innodb_file_per_table`が設定されていない)単一のテーブルではなく全テーブルの空きスペースを取ってきてしまいます。(省略) とあるので、他のテーブルの実装では共有空きスペースが発生しない定義だったのではないでしょうか。 (MySQL使ったことないので分かりませんが直観的には文字列やBLOB型が無い、とか。) 英語が読めるなら原文の方に行けばInnoDbの調整方法へのリンク等もあったのでそちらを参照してみては如何でしょうか。 余談ですが、Effectiveの列の値がマイナスの件については別の質問で以下のように回答されています。 その表示はマイナスじゃなくて「だいたい~」という意味を表すチルドです。 InnoDBは正確な行数を管理していないのでテーブルの大まかな行数を表示しています。 `COUNT(*)`メソッドを使えば正確な行数が取得できます。 とあります。