5

20万行以上を含むテーブルを持つデータベースがあるとします。
このテーブルには、ID 1800 の固定タプルがあります。残りのタプル シーケンスは 300k+ から始まります。
このテーブルをきれいにし、ID 1800 の 1 つのレジスタを削除せずにすべてのレコードを削除する必要があります。実行できる可能性のある 3 種類のクエリを思いつきました。

DELETE FROM table WHERE id > 1800
DELETE FROM table WHERE id <> 1800
DELETE FROM table WHERE id NOT IN (1800)

最初のものは他のものよりも速い気がしますが、他のすべてのデータの ID は 1800 をはるかに超えているため、確信が持てません。

どちらが速いですか、なぜですか? また、削除できないレコードを除いて、より早く削除する方法があれば教えてください。

4

4 に答える 4

9

ほとんどのデータベースで最も速い方法は次のとおりです。

  1. ID 1800 のレコードを一時テーブルに選択します
  2. 元のテーブルを削除
  3. 一時テーブルから完全なテーブルにデータをコピーします

確かに、これはトリガー、制約、および許可のために不可能な場合があります。多くのデータベースでは、(2) を変更して、テーブルを削除する代わりに切り捨てることで、同様のことを行うことができます。

元の質問に関しては、行とそれに関連付けられたデータを実際に削除することによるオーバーヘッドがクエリを支配します。比較の仕方は問いません。

サンプルコード

create temp table saved as
    select * from t where id = 1800

truncate table t

insert into t
    select * from saved

一時テーブルの Postgres 命名規則についてはよくわかりませんが、これがアイデアです。

于 2013-01-16T19:24:58.103 に答える
6

それらが同じレコードに影響を与える限り、それらは同様のパフォーマンスを持ちます。

前者は、より効率的な全テーブル スキャンではなく、インデックス シークを使用する可能性がわずかにありますが、無視できる程度です。

于 2013-01-16T19:25:27.983 に答える
3

ID を新しいテーブルに移動できない場合は、グループまたはバッチで試して削除することをお勧めします。レコードの大きなチャンクを伴うトランザクションを持つことは、最速で処理されない場合があります。これは、含まれているすべてのデータベース oracle および microsoft データベース製品に当てはまります。

BEGIN TRANSACTION;
DELETE FROM table WHERE id >= 0 and  id < 20000 and id != 1800;
COMMIT TRANSACTION;
BEGIN TRANSACTION;
DELETE FROM table WHERE id >= 20000 and  id < 40000 and id != 1800;
COMMIT TRANSACTION;
etc
etc
于 2013-01-16T19:36:22.433 に答える