遅い削除のクエリで問題があります。私はスキーマを持っている、例えば、 "デルタ"と言っても、他のテーブルに同じテーブル(同一のカラム&プライマリキー)を持つテーブルを含む "ターゲット"があります。デルタスキーマに表示されるすべての行をターゲットスキーマから削除する必要があります。私は、EXISTSアプローチからDELETE FROM WHERE EXISTSアプローチを使用してこれを試しましたが、それは非常に遅いようです。これはどこからのPostgresqlの遅い削除
CREATE TABLE name2phoneme
(
name_id uuid NOT NULL,
phoneme_id uuid NOT NULL,
seq_num numeric(3,0),
CONSTRAINT pk_name2phoneme PRIMARY KEY (name_id, phoneme_id),
CONSTRAINT fk_name2phoneme_name_id_2_name FOREIGN KEY (name_id)
REFERENCES name (name_id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
DEFERRABLE INITIALLY DEFERRED,
CONSTRAINT fk_name2phoneme_phoneme_id_2_phoneme FOREIGN KEY (phoneme_id)
REFERENCES phoneme (phoneme_id) MATCH SIMPLE
ON UPDATE NO ACTION
ON DELETE NO ACTION
DEFERRABLE INITIALLY DEFERRED
)
「ターゲット」テーブル(「デルタ」スキーマは、プライマリキーと外部キーを持っていることを除いwhith)両方のテーブルのレイアウトは
DELETE FROM "target".name2phoneme
WHERE EXISTS(
SELECT 1 FROM delta.name2phoneme d
WHERE name2phoneme.NAME_ID = d.NAME_ID
AND name2phoneme.PHONEME_ID = d.PHONEME_ID
);
である:ここではクエリの例ですもともとはわずか18M行を超えていましたが、デルタ表には約3.7M行(ターゲットから削除される)が含まれていました。
は、ここで上記のクエリのEXPLAINの出力です:
"Delete on name2phoneme (cost=154858.03..1068580.46 rows=6449114 width=12)"
" -> Hash Join (cost=154858.03..1068580.46 rows=6449114 width=12)"
" Hash Cond: ((name2phoneme.name_id = d.name_id) AND (name2phoneme.phoneme_id = d.phoneme_id))"
" -> Seq Scan on name2phoneme (cost=0.00..331148.16 rows=18062616 width=38)"
" -> Hash (cost=69000.01..69000.01 rows=3763601 width=38)"
" -> Seq Scan on name2phoneme d (cost=0.00..69000.01 rows=3763601 width=38)"
私は上記のクエリをANALYZE説明しようとしたが、実行には2時間を引き継いだので、私はそれを殺しました。
私はこの操作をどのように最適化できますか?
370万行を削除するとオーバーヘッドが大きくなります。 –
'WHERE(name_id、phoneme_id)IN(SELECT name_id、phoneme_id FROM other_table)を使用してみることができます。これは、あなたが望む行を持つ新しいテーブルを作成し、既存のテーブルを切り捨て、 (name_id、phoneme_id) 'にインデックスを追加しましたが、テーブルのサイズを指定すると、すばらしいものはまったく期待できませんでした。 – jcaron
@jcaron' 'DELETE FROM" target ".name2phoneme WHERE(name_id、 phoneme_id)を(SELECT d.name_id、d.phoneme_id FROM "delta" .name2phoneme d); 'に置き換えて、WHERE EXISTSアプローチと同じコストにしました。 –