という名前の MySQL テーブルの場合はmydb.mytable
、次を実行します。
OPTIMIZE TABLE mydb.mytable;
これを段階的に行うこともできます。
CREATE TABLE mydb.mytable_new LIKE mydb.mytable;
ALTER TABLE mydb.mytable_new DISABLE KEYS;
INSERT INTO mydb.mytable_new SELECT * FROM mydb.mytable;
ALTER TABLE mydb.mytable_new ENABLE KEYS;
ALTER TABLE mydb.mytable RENAME mydb.mytable_old;
ALTER TABLE mydb.mytable_new RENAME mydb.mytable;
ALTER TABLE mydb.mytable_old;
ANALYZE TABLE mydb.mytable;
いずれの場合も、テーブルは断片化されずに終了します。
試してみる !!!
更新 2012 年 12 月 3 日 12:50 EDT
を介した一括 INSERT で行が再利用されるかどうかが気になる場合はLOAD DATA INFILE
、次の点に注意してください。
MyISAM テーブルを作成したとき、デフォルトの行形式は動的であると想定しました。どちらかでそれが何であるかを確認できます
SHOW CREATE TABLE mydb.mytable\G
また
SELECT row_format FROM information_schema.tables
WHERE table_schema='mydb' AND table_name='mytable';
テーブルの行形式はDynamic
であるため、断片化された行のサイズはさまざまです。MyISAM ストレージ エンジンは、挿入される次のデータ セットが収まるかどうかを確認するために、削除された各行の長さをチェックし続けます。着信データが削除されたどの行にも収まらない場合は、新しい行データが追加されます。
そのような行の存在はmyisamchk
苦労する可能性があります。
これが、実行を推奨する理由ですOPTIMIZE TABLE
。そうすれば、データはより速く追加されます。
更新 2012-12-03 12:58 EDT
これはあなたができる興味深いことです: concurrent_insert を 2 に設定してみてください。そうすれば、テーブルのギャップをチェックせずに、常に MyISAM テーブルに追加できます。これにより、INSERT が劇的に高速化されますが、既知のギャップはすべてそのままになります。
を使用して、できるだけ早くテーブルをデフラグすることもできますOPTIMIZE TABLE
。
更新 2012 年 12 月 3 日 13:40 EDT
2 番目の提案を実行しないでください
CREATE TABLE mydb.mytable_new LIKE mydb.mytable;
ALTER TABLE mydb.mytable_new DISABLE KEYS;
INSERT INTO mydb.mytable_new SELECT * FROM mydb.mytable;
ALTER TABLE mydb.mytable_new ENABLE KEYS;
ALTER TABLE mydb.mytable RENAME mydb.mytable_old;
ALTER TABLE mydb.mytable_new RENAME mydb.mytable;
ANALYZE TABLE mydb.mytable;
これはあなたにアイデアを与えるでしょう
OPTIMIZE TABLE
実行にかかる時間
- 実行後に
.MYD
とがどれだけ小さくなるか.MYI
OPTIMIZE TABLE
私の2番目の提案を実行した後、それらを比較できます
SELECT
A.mydsize,B.mydsize,A.mydsize - B.mydsize myd_diff,
A.midsize,B.myisize,A.myisize - B.myisize myi_diff
FROM
(
SELECT data_length mydsize,index_length myisize
FROM information_schema.tables
WHERE table_schema='mydb' AND table_name='mytable'
) A,
(
SELECT data_length mydsize,index_length myisize
FROM information_schema.tables
WHERE table_schema='mydb' AND table_name='mytable_new'
) B;
更新 2012-12-03 16:42 EDT
ROW_FORMAT が固定に設定されているテーブルには、毎回同じ長さの行を割り当てる余裕があります。MyISAM テーブルが削除された行のリストを保持している場合、リストの最初の行は、データを挿入する次の行として常に選択する必要があります。十分な長さの適切な行ギャップが見つかるまで、リスト全体をトラバースする必要はありません。削除された各行は、DELETE
. 各 INSERT は、削除された行の最初の行を選択します。
MyISAM テーブルは同時挿入を実行できるため、これらのことを想定できます。この機能をconcurrent_insertオプションで利用できるようにするには、MyISAM テーブルへの INSERT で次の 3 つのうちの 1 つを検出できる必要があります。
- 削除された行のリストの存在、したがってリストからの選択
- Row_Format=Dynamic : 各行の長さが異なる削除された行のリスト
- Row_Format=Fixed : すべての行が同じ長さの削除された行のリスト
- 削除された行のリストがないため、追加されます
- 削除された行のリストの存在チェックをバイパスします ( concurrent_insertを 2 に設定)
検出 #1 を可能な限り高速にするには、MyISAM テーブルの row_format を Fixed にする必要があります。動的な場合は、リストのトラバーサルが必要になる可能性が非常に高くなります。