2013-07-25 43 views
0

我有一個100 GB大小的postgresql數據庫。其中一個表格有大約五十億條目。爲了快速輸入數據,一些數據被重複,稍後修剪。其中一列可用於將行標識爲唯一。刪除大postgresql數據庫表中的重複行

我發現this stackoverflow question這表明對MySQL的解決方案:

ALTER IGNORE TABLE table_name ADD UNIQUE (location_id, datetime) 

有什麼PostgreSQL的相似?

我試着用group和row number刪除,我的電腦在兩種情況下幾個小時後內存耗盡。

這是我所得到的,當我嘗試估算表中的行數:

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

你可以顯示你的表DDL和你正在執行的刪除語句嗎?如果您將刪除操作變爲選擇計數(*),您的刪除定位有多少行? – Kuberchaun

+0

@JustBob select count(1)在我停止之前花了一個多小時。 – nurettin

+0

我的想法是做批量刪除。我很好奇你的刪除是在2行還是3億後進行的。如果你有一個漂亮的索引列是一個序列,你可以在一組行上進行滑動並從那裏刪除。你將不得不寫一個python腳本或其他東西來循環刪除表中的最小和最大與提交之間的id。做到這一點,直到你到達表格的末尾,最小和最大變化範圍高於最後一個範圍,但仍然只會在說出50,000條記錄之後。合理? – Kuberchaun

回答

1

兩種解決方案立刻浮現在腦海:

1)。使用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