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에 따라 라이센스가 부여됩니다.