postgresql 중복 데이터 삭제의 몇 가지 방법 소결
5841 단어 postgresql되풀이데이터
또한 사용된 그룹 by 삭제 방법으로 효율이 높다.
또 하나는 방금 발견된 것으로 아직 검증되지 않았으니 이 세 가지 삭제 방법을 정리하고 각자의 실행 효율을 검증한다.
먼저 기초표를 만들고 일정량의 중복 데이터를 삽입합니다.
test=# create table deltest(id int, name varchar(255));
CREATE TABLE
test=# create table deltest_bk (like deltest);
CREATE TABLE
test=# insert into deltest select generate_series(1, 10000), 'ZhangSan';
INSERT 0 10000
test=# insert into deltest select generate_series(1, 10000), 'ZhangSan';
INSERT 0 10000
test=# insert into deltest_bk select * from deltest;일반 삭제 방법
가장 쉽게 떠오르는 방법은 데이터가 중복되었는지 판단하는 것이다. 중복된 데이터에 대해ctid의 최소(또는 최대)의 데이터만 보존하고 다른 데이터를 삭제하는 것이다.
test=# explain analyse delete from deltest a where a.ctid <> (select min(t.ctid) from deltest t where a.id=t.id);
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------
Delete on deltest a (cost=0.00..195616.30 rows=1518 width=6) (actual time=67758.866..67758.866 rows=0 loops=1)
-> Seq Scan on deltest a (cost=0.00..195616.30 rows=1518 width=6) (actual time=32896.517..67663.228 rows=10000 loops=1)
Filter: (ctid <> (SubPlan 1))
Rows Removed by Filter: 10000
SubPlan 1
-> Aggregate (cost=128.10..128.10 rows=1 width=6) (actual time=3.374..3.374 rows=1 loops=20000)
-> Seq Scan on deltest t (cost=0.00..128.07 rows=8 width=6) (actual time=0.831..3.344 rows=2 loops=20000)
Filter: (a.id = id)
Rows Removed by Filter: 19998
Total runtime: 67758.931 ms
test=# select count(*) from deltest;
count
-------
10000
(1 )id와 같은 데이터,ctid의 가장 작은 것을 보존하고 다른 삭제를 볼 수 있습니다.deltest표의 데이터를 절반으로 삭제하는 데 67s가 넘는 시간이 소요되는 셈이다.상당히 느리다.그룹 by 삭제 방법
두 번째 방법은 그룹 by 방법으로 그룹을 통해ctid의 가장 작은 데이터를 찾은 다음 다른 데이터를 삭제합니다.
test=# truncate table deltest;
TRUNCATE TABLE
test=# insert into deltest select * from deltest_bk;
INSERT 0 20000
test=# explain analyse delete from deltest a where a.ctid not in (select min(ctid) from deltest group by id);
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------
Delete on deltest a (cost=131.89..2930.46 rows=763 width=6) (actual time=30942.496..30942.496 rows=0 loops=1)
-> Seq Scan on deltest a (cost=131.89..2930.46 rows=763 width=6) (actual time=10186.296..30814.366 rows=10000 loops=1)
Filter: (NOT (SubPlan 1))
Rows Removed by Filter: 10000
SubPlan 1
-> Materialize (cost=131.89..134.89 rows=200 width=10) (actual time=0.001..0.471 rows=7500 loops=20000)
-> HashAggregate (cost=131.89..133.89 rows=200 width=10) (actual time=10.568..13.584 rows=10000 loops=1)
-> Seq Scan on deltest (cost=0.00..124.26 rows=1526 width=10) (actual time=0.006..3.829 rows=20000 loops=1)
Total runtime: 30942.819 ms
(9 )
test=# select count(*) from deltest;
count
-------
10000
(1 )같은 데이터의 절반을 삭제하고 그룹by를 사용하면 시간을 절반으로 절약할 수 있다.그러나 30s가 필요합니다. 세 번째 삭제 동작을 시도해 보겠습니다.새로운 삭제 방법
postgres 수련의 길 이 책에서 저자는 효율이 높은 삭제 방법을 언급했는데 여기서 구체적으로 다음과 같이 검증한다.
test=# truncate table deltest;
TRUNCATE TABLE
test=# insert into deltest select * from deltest_bk;
INSERT 0 20000
test=# explain analyze delete from deltest a where a.ctid = any(array (select ctid from (select row_number() over (partition by id), ctid from deltest) t where t.row_number > 1));
QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------
Delete on deltest a (cost=250.74..270.84 rows=10 width=6) (actual time=98.363..98.363 rows=0 loops=1)
InitPlan 1 (returns $0)
-> Subquery Scan on t (cost=204.95..250.73 rows=509 width=6) (actual time=29.446..47.867 rows=10000 loops=1)
Filter: (t.row_number > 1)
Rows Removed by Filter: 10000
-> WindowAgg (cost=204.95..231.66 rows=1526 width=10) (actual time=29.436..44.790 rows=20000 loops=1)
-> Sort (cost=204.95..208.77 rows=1526 width=10) (actual time=12.466..13.754 rows=20000 loops=1)
Sort Key: deltest.id
Sort Method: quicksort Memory: 1294kB
-> Seq Scan on deltest (cost=0.00..124.26 rows=1526 width=10) (actual time=0.021..5.110 rows=20000 loops=1)
-> Tid Scan on deltest a (cost=0.01..20.11 rows=10 width=6) (actual time=82.983..88.751 rows=10000 loops=1)
TID Cond: (ctid = ANY ($0))
Total runtime: 98.912 ms
(13 )
test=# select count(*) from deltest;
count
-------
10000
(1 )
상술한 결과를 보고 정말 놀랐습니다. 이렇게 빨리 삭제하는 방법은 처음 보았습니다. 자신의 진실하고 견문이 좁습니다. 여기서 수련의 도라는 책의 대신작가에게 경배해야 합니다.보충: pgsql 삭제표의 중복 데이터 보존 중 하나
1. 테이블(테이블 이름:table 키:id)에 필드rownum을 추가합니다. 형식은 serial입니다.
2. 실행 문장:
delete from table where rownum not in(
select max(rownum) from table group by id
)3. 마지막으로 rownum 삭제이상의 개인적인 경험으로 여러분께 참고가 되었으면 좋겠습니다. 또한 많은 응원 부탁드립니다.만약 잘못이 있거나 완전한 부분을 고려하지 않으신다면 아낌없이 가르침을 주시기 바랍니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
postgresql의 jsonb 데이터 조회 및 수정 방법jsonb PostgreSQL 문서에서 정의한 데이터 형식 json과 jsonb는 거의 같다.관건적인 차이점은 json 데이터는 JSON 입력 텍스트의 정확한 복사본으로 저장되고 jsonb는 분해된 2진 형식으로 데...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.