sql - 有什么方法可以改进我的 PostgreSQL 上的这个查询吗?
问题描述
我最近用 postgres 创建了一个数据仓库。在一个特定的表中,我总共加载了 29 Mi 行。
我试图通过生成的 MD5 识别相同的行。问题是需要一天多的时间来处理和消除重复。使用的所有列都带有索引。
查询:
DELETE FROM
elos_sched_2 es
WHERE
ES.SCHED_ID IN
( SELECT
ELOS_SCHED_2
GROUP BY
HASHID
HAVING
COUNT(1) > 1 )
这是查询生成的“解释”:
Delete on elos_sched_2 es (cost=7190318.45..7191769.30 rows=11673374 width=38)
-> Nested Loop (cost=7190318.45..7191769.30 rows=11673374 width=38)
-> HashAggregate (cost=7190317.88..7190319.88 rows=200 width=40)
Group Key: "ANY_subquery".min
-> Subquery Scan on "ANY_subquery" (cost=6618114.99..7152680.62 rows=15054907 width=40)
-> GroupAggregate (cost=6618114.99..7002131.55 rows=15054907 width=41)
Group Key: elos_sched_2.hashid
Filter: (count(1) > 1)
-> Sort (cost=6618114.99..6676481.86 rows=23346749 width=41)
Sort Key: elos_sched_2.hashid
-> Seq Scan on elos_sched_2 (cost=0.00..1606287.49 rows=23346749 width=41)
-> Index Scan using idx_sched_id_elos_sched_2 on elos_sched_2 es (cost=0.56..8.58 rows=1 width=14)
Index Cond: (sched_id = "ANY_subquery".min)
仅凭这个结果就可以看出任何机会吗?
谢谢!
解决方案
这会更快。首先提取和具体化 SCHED_ID-s 以删除,然后删除它们。
如果您的 Postgres 版本低于 12 MATERIALIZED
,则从查询中删除,因为 CTE-s 总是物化。
with MATERIALIZED delete_list(id_to_delete) as
(
select MIN(SCHED_ID)
from elos_sched_2
group by HASHID
having COUNT(1) > 1
)
delete from elos_sched_2
where SCHED_ID in (select id_to_delete from delete_list);
顺便
说一句,如果每个 有多个重复项hashid
怎么办?查询逻辑应该倒置。
with MATERIALIZED keep_list(id_to_keep) as
(
select MAX(sched_id)
from elos_sched_2
group by hashid
)
delete from elos_sched_2
where sched_id NOT in (select id_to_keep from keep_list);
推荐阅读
- reactjs - Lottie 动画在单击包含它的图层时开始播放,如何停止?
- cytoscape.js - 父节点的可见性影响子节点的不透明度
- python-2.7 - 项目的 Python 和 GCP getIamPolicy
- java-8 - 使用标准条件对流进行分组,而不使用 forEach 和两个外部列表
- java - MultiPart 内存问题
- powerbi - 返回 power BI 中存在的最新值
- javascript - kafka-node 设置生产者选项
- javascript - 随机打开一个具有不同类号jQuery的随机弹出div
- msbuild - MsBuild SDK 项目风格:项目依赖有时会失败
- javascript - React 将 setstate 作为一个函数