【问题标题】:postgresql delete partition tablespostgresql 删除分区表
【发布时间】:2015-01-19 03:14:13
【问题描述】:

我是 Postgresql 的新手,不完全了解如何管理分区表。
我有基于天的分区表。在插入数据之前,触发器会检查日期并放入相应的子表中。
例如。
11.15.2014 - 插入名为 11-15-2014_log 的表中。
11.16.2014 - 插入名为 11-16-2014_log 的表中。
现在我想创建将删除旧子表的函数,例如,超过 90 天的表。 我应该根据表名查找并删除子表(因为它包含创建日期)还是应该在主表中查找超过 90 天的记录??
任何建议或提示将不胜感激。谢谢。

【问题讨论】:

  • 不知道您正在处理多少数据或运行频率,甚至不知道它使用什么语言,因此很难提出任何建议。你能展示一下创建表的触发器函数吗?
  • 这些表的平均预期大小是多少?也就是说,你真的需要对它们进行分区吗?

标签: function postgresql partition


【解决方案1】:

我将只删除主表中较旧的记录,例如:

DELETE FROM master_table WHERE creation_date < 'today' - INTERVAL '90 days';

但是我的建议是将此查询安排在服务器最睡眠时间运行,例如早上 5:00

【讨论】:

    【解决方案2】:

    对于最终在这里寻找如何删除 PostgreSQL 中的表分区的任何人,这里是现代答案。

    解决方案是不使用 DELETE 语句,因为这将删除数据而不删除保存数据的相应表分区。 OP 询问管理分区表,而不是删除记录,因此任何使用 DELETE 语句的解决方案都会增加删除记录的不必要的数据库开销,保留空分区表,并完全忽略使用分区的主要好处之一;当表格不再有用时将其删除。

    在这种情况下,解决方案必须是 DROP 不再需要的分区表。我在生产环境中写了一个解决方案来解决这个问题,答案是here

    为了解决 OP 的问题,我编写的函数可以通过两次轻微的修改来修改 fullTablename 变量和日期格式。 fullTablename 变量行必须从

    fullTablename := base_table_name || '_' || to_char(startTime, dateFormat);
    

    到 YYYY-MM-DD_log 这样的格式

    fullTablename := to_char(startTime, dateFormat) || '_' || base_table_name;
    

    那么日期格式需要从

    稍微修改一下
    WHEN partition_plan='day'   THEN 'YYYYDDD'
    

    按照规定的表命名约定

    WHEN partition_plan='day'   THEN 'YYYY-MM-DD'
    

    然后可以从日常维护脚本中调用调用该函数执行清理的 SQL 查询,如下所示:

    SELECT public.drop_partitions(current_date-180, 'public', 'log', 5, 'day');
    

    这将删除比 180 天前 5 天的 YYYY-MM-DD_log 表。对于删除数十或数百个旧表分区的初始运行,可以将 5 设置为更高的值以达到预期的效果。

    【讨论】:

      【解决方案3】:

      关于删除分区,下面的例子删除了sales表的一个分区。使用以下命令创建销售表:

      CREATE TABLE sales
      (
        dept_no     number,   
        part_no     varchar2,
        country     varchar2(20),
        date    date,
        amount  number
      )
      PARTITION BY LIST(country)
      (
        PARTITION europe VALUES('FRANCE', 'ITALY'),
        PARTITION asia VALUES('INDIA', 'PAKISTAN'),
        PARTITION americas VALUES('US', 'CANADA')
      );
      

      查询ALL_TAB_PARTITIONS 视图显示分区名称:

      acctg=# SELECT partition_name, server_name, high_value FROM ALL_TAB_PARTITIONS;
       partition_name | server_name |     high_value      
      ----------------+-------------+---------------------
       europe         | seattle     | 'FRANCE', 'ITALY'
       asia           | chicago     | 'INDIA', 'PAKISTAN'
       americas       | boston      | 'US', 'CANADA'
      (3 rows)
      

      要从 sales 表中删除 americas 分区,请调用以下命令:

      ALTER TABLE sales DROP PARTITION americas;
      

      查询ALL_TAB_PARTITIONS视图表明分区已成功删除:

      acctg=# SELECT partition_name, server_name, high_value FROM ALL_TAB_PARTITIONS;
       partition_name |     high_value      
      ----------------+---------------------
       asia           | 'INDIA', 'PAKISTAN'
       europe         | 'FRANCE', 'ITALY'
      (2 rows)
      

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-11-17
      • 1970-01-01
      • 2012-01-08
      • 2021-09-12
      • 1970-01-01
      • 2018-05-18
      • 1970-01-01
      • 2020-01-07
      相关资源
      最近更新 更多