GreenPlum中的分区表在数据量较大的情况下对于提升查询性能的帮助非常的,但是GreenPlum本身并没有提供分区表自动维护的工具,这里我们利用GreenPlum的PL/SQL自定义两个分区表自动维护的存储过程(也可以成为函数)。
创建存储过程之前首先要创建一个记录分区表详细信息的视图,这里可以参见上篇博文。由于业务中有多张表需要做分区,而且分区字段的类型并不一样,因此我们首先创建一张字典表,记录每张表的分区类型,如下:
CREATE TABLE op_tb_partition ( tb_name varchar(100) DEFAULT NULL, timetype varchar(8) DEFAULT NULL )DISTRIBUTED BY (tb_name); select * from op_tb_partition; tb_name | timetype -----------------------------+---------- nl_app_action_error_trace | unixtime nl_mob_app_anr_data | usertime nl_mob_app_error_trace_test | datetime (3 rows)
创建添加分区的存储过程,GreenPlum中单引号的转义符为两个单引号,详细代码如下:
create or replace function add_partition_day() returns text as $$ declare tb_options record; declare curr_part varchar(8); declare max_part varchar(20); declare part_name varchar(9); declare end_part varchar(8); declare start_range int; declare end_range int; declare x int; begin for tb_options in select * from op_tb_partition group by tb_name,timetype loop if tb_options.timetype = ‘datetime‘ then select replace(substring(current_date + interval ‘7 day‘ from 1 for 10),‘-‘,‘‘) as date into max_part; select substring(max(partition_name) from 2 for 8) into curr_part from v_gp_range_partition_meta a join pg_class b on a.table_name=b.oid where b.relname =tb_options.tb_name; select date(max_part) - date(curr_part) into x; while x > 0 loop select replace(substring(date(curr_part) + interval ‘1 day‘ from 1 for 10),‘-‘,‘‘) as date into curr_part; select replace(substring(date(curr_part) + interval ‘1 day‘ from 1 for 10),‘-‘,‘‘) as date into end_part; select ‘p‘ || curr_part into part_name; execute ‘alter table ‘ || tb_options.tb_name || ‘ add partition ‘ || part_name || ‘ start (‘‘‘ || curr_part || ‘‘‘::date) end (‘‘‘ || end_part || ‘‘‘::date)‘; x = x-1; end loop; end_part = ‘‘; end_range = 0; elsif tb_options.timetype = ‘usertime‘ then select replace(substring(current_date + interval ‘7 day‘ from 1 for 10),‘-‘,‘‘) as date into max_part; select substring(max(partition_name) from 2 for 8) into curr_part from v_gp_range_partition_meta a join pg_class b on a.table_name=b.oid where b.relname =tb_options.tb_name; select date(max_part) - date(curr_part) into x; while x > 0 loop select replace(substring(date(curr_part) + interval ‘1 day‘ from 1 for 10),‘-‘,‘‘) as date into curr_part; select replace(substring(date(curr_part) + interval ‘1 day‘ from 1 for 10),‘-‘,‘‘) as date into end_part; select nl_to_timestamp(date(curr_part)) into start_range; select nl_to_timestamp(date(end_part)) into end_range; select ‘p‘ || curr_part into part_name; execute ‘alter table ‘ || tb_options.tb_name || ‘ add partition ‘ || part_name || ‘ start (‘ || start_range || ‘::int) end (‘ || end_range || ‘::int)‘; -- alter table tb_options.tb_name add partition part_name start (start_range::int) end (end_range::int); x = x-1; end loop; end_part = ‘‘; end_range = 0; elsif tb_options.timetype = ‘unixtime‘ then select replace(substring(current_date + interval ‘7 day‘ from 1 for 10),‘-‘,‘‘) as date into max_part; select substring(max(partition_name) from 2 for 8) into curr_part from v_gp_range_partition_meta a join pg_class b on a.table_name=b.oid where b.relname =tb_options.tb_name; select date(max_part) - date(curr_part) into x; while x > 0 loop select replace(substring(date(curr_part) + interval ‘1 day‘ from 1 for 10),‘-‘,‘‘) as date into curr_part; select replace(substring(date(curr_part) + interval ‘1 day‘ from 1 for 10),‘-‘,‘‘) as date into end_part; select unix_timestamp(date(curr_part)) into start_range; select unix_timestamp(date(end_part)) into end_range; select ‘p‘ || curr_part into part_name; execute ‘alter table ‘ || tb_options.tb_name || ‘ add partition ‘ || part_name || ‘ start (‘ || start_range || ‘::int) end (‘ || end_range || ‘::int)‘; -- alter table tb_options.tb_name add partition part_name start (start_range::int) end (end_range::int); x = x-1; end loop; end_part = ‘‘; end_range = 0; end if; end loop; return ‘ok‘; end; $$ LANGUAGE plpgsql;
创建删除分区的存储过程,这里的数据保存3个月,详细代码如下:
调用声明好的存储过程,如下:
时间: 2024-11-11 12:37:11