- 2007-11-02
- pgsql
そういう時はdeleteではなくtruncateを使う方法もあります。 truncateはいきなりテーブルを(不要領域を残すことなく)空っぽにするSQLです。
なので、とても大きいテーブルのごく一部のデータだけ残して他を消す手順としては、
- 同じテーブルレイアウトの一時保存先となるテーブルを作る
- 一時保存先のテーブルにレコードを移行する
- 元のテーブルをtruncate
- 一時保存先のテーブルからレコードを戻す
- 一時保存先テーブルをdrop
この手順であればテーブルのOIDも変わりません。
残すレコードが多ければ、3と4の間で一旦インデックスを削除して、5の後でインデックスを作り直した方がいいかもしれません。あと、一時保存先のテーブルは、CREATE TEMPORARY TABLEを使った方が速い(し、最後にテーブルをdropする手間も省ける)と思います。
なので全体的な操作としては、
CREATE TEMP TABLE items_temp SELECT * FROM items LIMIT 0;
INSERT INTO items_temp SELECT * FROM items WHERE ...;
TRUNCATE items;
INSERT INTO items SELECT * FROM items_temp;
といった感じです。もう一つついでに。
CREATE TABLE items_new AS SELECT * FROM items LIMIT 0;
は、
CREATE TABLE items_new (LIKE items);
と書くこともできます。この"LIKEほげほげ"は、(今回は必要ありませんが)オプションによって制約やデフォルト値もコピーでき、 また以下のように、カラムを追加することもできるので、「似てるけどちょっと違うテーブル」を作る時に便利です。
CREATE TABLE items_new (newcol1 int, LIKE items, newcol2 int);