如何解决什么是清除我的Postgresql数据库中大量不必要数据的有效方法
我必须从我的Postgresql数据库中删除一些不必要的数据。 这是适用于小数据的查询:
mass
在CTE中,您会发现我添加了一个限制,否则查询将永远无法完成。在没有限制的情况下,CTE会产生937,147行。有5条delete语句。每个删除可能至少有一行并且可能是3最多5行 我有3个问题:
- 查询是否可以改进?我应该使用联接而不是子查询? 我应该将一个脚本分割成多个脚本,而不是一个脚本吗?
- 第二个问题是我应该使用pg_cron吗?
- 如果我不设置限制,它将能够处理吗?
我知道这将是一项耗时的工作,尽管如此,但至少它应该可以工作。不应该挂起。昨天我在没有LIMIT的情况下运行了它,并且运行了几个小时后挂起了所有删除操作,但是早些时候它的限制很小,例如10到100。
更新根据建议,我介绍了临时表,并使用子查询将其删除到临时表。这是脚本:
mass
UPDATE-2
disable_triggers.sql
WITH bad_row_history(survey_id,template_id) AS ((
SELECT row_id,(row_value->>'template_id')::INTEGER
FROM public.row_history
WHERE record_table='survey_storage'
AND row_value->>'status'IN ('Never Surveyed','Incomplete Configuration')
AND row_id NOT IN (
SELECT row_id
FROM public.row_history
WHERE record_table='survey_storage'
AND row_value->>'status'='Ready to Launch'
)
) LIMIT 10),delete_su AS (
DELETE FROM survey_user
WHERE survey_id = ANY(ARRAY(select survey_id FROM bad_row_history))
),delete_slu AS(
DELETE FROM survey_library_users
WHERE survey_library_id = ANY(ARRAY(select template_id FROM bad_row_history))
),delete_ss AS(
DELETE FROM survey_storage
WHERE id = ANY(ARRAY(select survey_id FROM bad_row_history))
),delete_sl AS(
DELETE FROM survey_library
WHERE id = ANY(ARRAY(select template_id FROM bad_row_history))
)
delete FROM row_history
WHERE row_id = ANY(ARRAY(select survey_id FROM bad_row_history))
脚本
DROP bad_row_history if EXISTS;
CREATE TEMPORARY TABLE bad_row_history (
survey_id int8 NOT NULL,template_id int8 NOT NULL
);
ANALYZE bad_row_history;
INSERT INTO bad_row_history(survey_id,template_id)
(SELECT row_id,'Incomplete Configuration')
AND row_id NOT IN (
SELECT row_id
FROM public.row_history
WHERE record_table='survey_storage'
AND row_value->>'status'='Ready to Launch'
)
);
DELETE FROM survey_user
WHERE survey_id IN (select survey_id FROM bad_row_history);
DELETE FROM survey_library_users
WHERE survey_library_id IN(select template_id FROM bad_row_history);
DELETE FROM survey_storage
WHERE id IN(select survey_id FROM bad_row_history);
DELETE FROM survey_library
WHERE id IN(select template_id FROM bad_row_history);
delete FROM row_history
WHERE row_id IN(select survey_id FROM bad_row_history)
enable_triggers.sql
ALTER TABLE survey_user DISABLE TRIGGER ALL;
ALTER TABLE survey_storage DISABLE TRIGGER ALL;
ALTER TABLE survey_library DISABLE TRIGGER ALL;
解决方法
不是像一个语句那样做所有事情,而是像这样:
-
根据第一个CTE的结果创建一个临时表。
-
ANALYZE
那个临时表。 -
在每个表中运行一个
DELETE
语句,并与临时表联接。
查询的问题是Postgres正在实现CTE,即计算约100万行并将其存储在内存中,然后删除查询将其分别转换为数组5次,这非常昂贵且缓慢。
我认为,您可以通过不转换为数组来加快速度,即
survey_library_id IN (select template_id FROM bad_row_history)
而不是
survey_library_id = ANY(ARRAY(select template_id FROM bad_row_history))
我可能会做的是使bad_row_history成为具有template_id,survey_id等列的临时表,然后将删除作为带有子选择的单独语句运行在临时表上。这样,优化程序应该能够在每次删除操作时更有效地工作。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。