2

サイズが 100 GB の postgresql データベースがあります。テーブルの 1 つには、約 5 億のエントリがあります。迅速なデータ入力のために、一部のデータは繰り返され、後で剪定するために残されました。列の 1 つを使用して、行が一意であることを識別できます。

mysqlの解決策を提案するこのstackoverflowの質問を見つけました:

ALTER IGNORE TABLE table_name ADD UNIQUE (location_id, datetime)

postgresqlに似たものはありますか?

グループ化と行番号で削除しようとしましたが、どちらの場合も数時間後にコンピューターのメモリが不足します。

これは、テーブル内の行数を推定しようとしたときに得られるものです。

SELECT reltuples FROM pg_class WHERE relname = 'orders';
  reltuples  
-------------
 4.38543e+08
(1 row)
4

1 に答える 1

1

2 つの解決策がすぐに思い浮かびます。

1)。select * from source table として新しいテーブルを作成し、WHERE 句を使用して一意の行を決定します。ソース テーブルと一致するようにインデックスを追加し、トランザクションで両方の名前を変更します。これが機能するかどうかは、空きディスク領域の量、テーブルが常に使用されており、アクセスの中断が許容されるかどうかなど、いくつかの要因によって異なります。新しいテーブルを作成すると、データとインデックスを密に圧縮できるという利点があります。 、一意でない行が省略されるため、テーブルは元のテーブルよりも小さくなります。

2)。列に部分的な一意のインデックスを作成し、WHERE 句を追加して、一意でないものを除外します。例えば:

test=# create table t ( col1 int, col2 int, is_unique boolean);
CREATE TABLE

test=# insert into t values (1,2,true), (2,3,true),(2,3,false);
INSERT 0 3

test=# create unique index concurrently t_col1_col2_uidx on t (col1, col2) where is_unique is true;
CREATE INDEX

test=# \d t
        Table "public.t"
  Column   |  Type   | Modifiers 
-----------+---------+-----------
 col1      | integer | 
 col2      | integer | 
 is_unique | boolean | 
Indexes:
    "t_col1_col2_uidx" UNIQUE, btree (col1, col2) WHERE is_unique IS TRUE
于 2013-07-25T14:49:39.663 に答える