【问题标题】:Delete from a table on basis of indexed columns is taking for ever根据索引列从表中删除是永远的
【发布时间】:2019-11-02 03:05:40
【问题描述】:

我们有一个包含三个索引列的表 bigint 类型的 column1 没有时区的时间戳类型的 column2 没有时区的时间戳类型的 column3 该表有超过 12 千万条记录,我们正在尝试使用以下查询删除所有大于当前日期 - 45 天的记录

delete from tableA
where column2 <= '2019-04-15 00:00:00.00' 
OR column3 <= '2019-04-15 00:00:00.00';

这是永远执行的,永远不会完成。

有什么方法可以提高这个查询的性能。

删除索引、删除数据并重新创建索引。但这不起作用,因为即使删除索引后我也无法删除数据。

 delete 
 from tableA 
 where column2 <= '2019-04-15 00:00:00.00' 
 OR column3 <= '2019-04-15 00:00:00.00'

我不想更改查询,但希望通过某些属性配置 Postgres,以便它能够删除记录

【问题讨论】:

  • "无法删除数据" "永远占用"​​span>
  • 更新您的问题,添加您的 tableA 架构(包括索引)并告诉我们您的 tableA 中有多少行(数百万 ?????)

标签: postgresql


【解决方案1】:

另请参阅Best way to delete millions of rows by ID 对问题的良好讨论

12 千万 == 1.2 亿行?

从大型索引表中删除很慢,因为在此过程中会多次重建索引。如果您可以选择要保留的行并使用它们来创建新表,然后删除旧表,则该过程会快得多。如果您定期执行此操作,请使用表分区并在需要时断开分区,然后可以将其删除。

1) 检查日志,您可能遇到了死锁。

2) 尝试创建一个新表,选择您需要的数据,然后删除并重命名。在查询中使用索引中的所有列。 DROP TABLE 比 DELETE .. FROM 快得多

    CREATE TABLE new_table AS (
        SELECT * FROM old_table WHERE 
        column1 >= 1 AND column2 >= current_date - 45 AND column3 >= current_date - 45);
    DROP TABLE old_table;
    ALTER TABLE new_table RENAME TO old_table;
    CREATE INDEX ...

3) 使用基于日期的分区创建一个新表,其中包含 15、30 或 45 天的表(如果您定期删除 45 天前的数据)。详情请见https://www.postgresql.org/docs/10/ddl-partitioning.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-31
    • 1970-01-01
    • 2022-11-17
    • 2011-01-30
    • 1970-01-01
    • 1970-01-01
    • 2020-03-15
    相关资源
    最近更新 更多