GreenPlum中自定义分区维护函数

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

GreenPlum中自定义分区维护函数的相关文章

GreenPlum中自定义时间转换函数

最近数据库架构调整,一部分业务从MySQL迁移到GreenPlum上去,原来MySQL中自带有unix_timestamp和from_unixtime两个函数可以实现标准时间和UNIX时间的相互转换,翻了下GreenPlun的文档,没有发现有类似的函数,于是便使用python自定义了这两个函数,并在这两个函数的基础上实现了两个业务相关的函数,这里记录一下. 1.首先创建一个python language. testdb=# create language plpythonu; CREATE LA

GreenPlum中自定义查询表分区的视图

GreenPlum中查询分区表的信息本身并不是特别的友好,需要做表关联并且做相应的处理,为了后期维护起来方便,这里创建两个视图供DBA直接查询,非常的方便. 1.创建list分区表的视图 create or replace view v_gp_list_partition_meta as  SELECT  pp.parrelid::regclass table_name, pr1.parchildrelid::regclass child_tbl_name, pr1.parname as par

在hadoop作业中自定义分区和归约

当遇到有特殊的业务需求时,需要对hadoop的作业进行分区处理 那么我们可以通过自定义的分区类来实现 还是通过单词计数的例子,JMapper和JReducer的代码不变,只是在JSubmit中改变了设置默认分区的代码,见代码: //1.3分区 //设置自定义分区类 job.setPartitionerClass(JPartitioner.class); //设置分区个数--这里设置成2,代表输出分为2个区,由两个reducer输出 job.setNumReduceTasks(2); 自定义的JP

Mapreduce中自定义分区

Reducer任务的数据来自于Mapper任务,也就说Mapper任务要划分数据,对于不同的数据分配给不同的Reducer任务运行.Mapper任务划分数据的过程就称作Partition.负责实现划分数据的类称作Partitioner. 默认的分区类是HashPartitioner,是处理Mapper任务输出的,getPartition()方法有三个形参,key.value分别指的是Mapper任务的输出,numReduceTasks指的是设置的Reducer任务数量,默认值是1.那么任何整数与

eCos系统无法正确链接到在C++源文件中自定义的cyg_user_start函数的问题和解决办法

在C++源文件中定义cyg_user_start函数前,将其声明成C函数,即可解决问题. eCos官网:http://ecos.sourceware.org eCos中文技术网:http://www.52ecos.net eCos交流QQ群:144940146. http://blog.csdn.net/zoomdy/article/details/39396085 mingdu.zheng<at>gmail<dot>com 问题: 在C++源文件中定义cyg_user_start

关于MapReduce中自定义分区类(四)

MapTask类 在MapTask类中找到run函数 if(useNewApi){       runNewMapper(job, splitMetaInfo, umbilical, reporter);     } 再找到runNewMapper @SuppressWarnings("unchecked")   private<INKEY,INVALUE,OUTKEY,OUTVALUE>   void runNewMapper(final JobConf job,    

C程序中引用自定义的C函数模块

我们知道,刚开始接触C语言编程,一般都是在一个.c或者.cpp(以下只说.c)的文件中编写代码,其中一定会有一个入口函数, 也就是main()函数,你可以将程序代码全部写在main函数里,当然如果你想要程序更加模块化,也可以将一些操作写在一个函数 里,这些函数的声明和定义也都是在main函数中. 想想,随着你的代码量越来越大,实现的功能越来越多,在一个.c文件中,你定义了许许多多的函数,这些函数实现着不同功能, 并且都是混杂在一起,你会不会感觉看着自己写的代码感觉自己的脑子也乱了?在这里我找到了

在复数类中自定义类型转换函数实现复数和非复数之间的运算

实现复数+double型数据,并且打印运算后实部上的数据 #include <iostream> using namespace std; class Complex { public: Complex( )//定义默认构造函数初始化复数 { real=0; imag=0; } //使用初始化表初始化复数 Complex(double r, double i):real(r),imag(i){} //定义自定义类型转换函数 operator double() { return real; }

SQL Server中自定义函数:用指定的分隔符号分割字符串

2014-11-13 微软SQL Server数据库中包含了很多内置的函数,入下图: 它们用于处理日期.数学.元数据.字符串等. 其中最为常用的就是处理字符串,里面包含了CharIndex()等函数,非常方便使用. 但是对于 特殊字符串的处理,比如:ISBN号 '978-7-5007-7234-7',如果想获取第三个与第四个分割符号之间的数字, 那么SQL 内置函数无法直接做到.这时就需要自定义函数.下面自定义三个函数,用于处理特殊的字符串. 一.按指定符号分割字符串,返回分割后的元素个数 1