9

私はかなりのデータベースを持っています...それほど大きなデータベースではありません-合計で約1GBのデータです。

複数のテーブルからいくつかの行を削除する必要があります。たとえば、私はテーブルを持っています

 Order
 id     | ... | status   | ...
 1      | ... | 1        | ...
 ...
 40     | ... | 20       | ...
 41     | ... | 1        | ...
 ...
 470000 | ... | 12       | ...

今、私は持っているすべての注文を削除したいですstatus=1

私はそれを行うと思います:

DELETE FROM Order WHERE status=1

すべてが素晴らしくシンプルに見えますが、それには時間がかかります!このクエリを実行すると、40 分後もまだ 100% の CPU 使用率で実行されていました...プロセスを強制終了しても、何も削除されませんでした。

を使用してスコープを制限しようとしたとき

DELETE FROM Order WHERE status=1 AND id<1000

約200行を削除するのに数分かかりました....

構成に欠けているものはありますか? 検索/確認/変更する必要があるものはありますか? なぜそんなに血なまぐさい非効率なのか、何か考えはありますか?

私は通常MySQLで作業しており、このpostgresデータベースを管理する必要がありますが、postgresの経験はまったくないため、非常に単純なものかもしれません.

インデックスは、id 列と status 列の両方にあります。

テーブルには約 50 万行あり、約半分を削除する必要があります。

実行計画:

Delete  (cost=0.00..19474.19 rows=266518 width=6)
->  Seq Scan on Orders  (cost=0.00..19474.19 rows=266518 width=6)
Filter: (statusid = 1)

あらゆる種類のトリガーやルールはありません。さらに、これはテーブルの新しいコピーであるとは言いませんでした。つまり、エクスポート/インポートで他のサーバーから移動されたということです。おそらく、これは何らかの役割を果たしていますか?

インデックスの削除は役に立ちますか?

4

2 に答える 2

10

プロセスを強制終了した後に何も削除されていないことは、まさにあなたが見るべきものです。

削除はトランザクションとして発生します。つまり、すべてが削除されるか、何も削除されません。これを確実に行うには、行を削除する前に行をどこかにコピーする必要があります。つまり、25 万行を削除するには、その数の行を挿入するのと同じくらいの時間がかかります。場合によっては、すべてを削除せずに新しいテーブルを作成し、新しいテーブルの名前を古いテーブルに変更する方が高速な場合があります。

これが別のデータベースから移動されている場合は、最初から 250k 行が挿入されないようにすることができれば、おそらくより良い結果が得られるでしょう。

(これは一般的な RDBMS の知識であり、postgresql 固有のものではありません。postgres MVCC の動作の詳細は大きく異なる場合があります。)

于 2011-10-24T18:06:09.543 に答える