postgresql 分区表创建及测试
1 建立分区
1.1. 创建主表
CREATE TABLE measurement (
city_id int not null,
logdate date not null,
peaktemp int,
unitsales int
);
CREATE TABLE
这里date类型精确到天,如'2006-02-01',如果时间精确到秒,如'2013-01-09 00:00:00' 使用timestamp 类型
1.2. 创建分区表
CREATE TABLEmeasurement_y2006m01 (
CHECK (logdate >= DATE '2006-01-01' AND logdate < DATE '2006-02-01' )
) INHERITS (measurement);
CREATE TABLE measurement_y2006m02 (
CHECK (logdate >= DATE '2006-02-01' AND logdate < DATE '2006-03-01' )
) INHERITS (measurement);
CREATE TABLE measurement_y2006m03 (
CHECK (logdate >= DATE '2006-03-01' AND logdate < DATE '2006-04-01' )
) INHERITS (measurement);
CREATE TABLE measurement_y2006m04 (
CHECK (logdate >= DATE '2006-04-01' AND logdate < DATE '2006-05-01' )
) INHERITS (measurement);
CREATE TABLE measurement_y2006m05 (
CHECK (logdate >= DATE '2006-05-01' AND logdate < DATE '2006-06-01' )
) INHERITS (measurement);
CREATE TABLE measurement_y2006m06 (
CHECK (logdate >= DATE '2006-06-01' AND logdate < DATE '2006-07-01' )
) INHERITS (measurement);
CREATE TABLE measurement_y2006m07 (
CHECK (logdate >= DATE '2006-07-01' AND logdate < DATE '2006-08-01' )
) INHERITS (measurement);
CREATE TABLE measurement_y2006m08 (
CHECK (logdate >= DATE '2006-08-01' AND logdate < DATE '2006-09-01' )
) INHERITS (measurement);
CREATE TABLE measurement_y2006m09 (
CHECK (logdate >= DATE '2006-09-01' AND logdate < DATE '2006-10-01' )
) INHERITS (measurement);
CREATE TABLE measurement_y2006m10 (
CHECK (logdate >= DATE '2006-10-01' AND logdate < DATE '2006-11-01' )
) INHERITS (measurement);
CREATE TABLE measurement_y2006m11 (
CHECK (logdate >= DATE '2006-11-01' AND logdate < DATE '2006-12-01' )
) INHERITS (measurement);
CREATE TABLE measurement_y2006m12 (
CHECK (logdate >= DATE '2006-12-01' AND logdate < DATE '2007-01-01' )
) INHERITS (measurement);
CREATE TABLE
1.3. 分区键上建索引
CREATE INDEX measurement_y2006m02_logdateON measurement_y2006m02 (logdate);
CREATE INDEX measurement_y2006m03_logdateON measurement_y2006m03 (logdate);
CREATE INDEX measurement_y2006m04_logdateON measurement_y2006m04 (logdate);
CREATE INDEX measurement_y2006m05_logdateON measurement_y2006m05 (logdate);
CREATE INDEX measurement_y2006m06_logdateON measurement_y2006m06 (logdate);
CREATE INDEX measurement_y2006m07_logdateON measurement_y2006m07 (logdate);
CREATE INDEX measurement_y2006m08_logdateON measurement_y2006m08 (logdate);
CREATE INDEX measurement_y2006m09_logdateON measurement_y2006m09 (logdate);
CREATE INDEX measurement_y2006m10_logdateON measurement_y2006m10 (logdate);
CREATE INDEX measurement_y2006m11_logdateON measurement_y2006m11 (logdate);
CREATE INDEX measurement_y2006m12_logdateON measurement_y2006m12 (logdate);
CREATE INDEX
执行insert into measurement命令向表中插入数据,希望数据按一定的规则插入相应分区,需要前期人工处理下,这里有两种策略,建立触发器和RULE规则。建立触发器方法需要1.4、1.5两步操作,1.6是建立RULE规则方法。
1.4. 创建触发器函数
CREATE OR REPLACEFUNCTION measurement_insert_trigger()
RETURNSTRIGGER AS $$
BEGIN
IF ( NEW.logdate >= DATE '2006-01-01'AND
NEW.logdate < DATE '2006-02-01' )THEN
INSERT INTO measurement_y2006m01 VALUES(NEW.*);
ELSIF ( NEW.logdate >= DATE '2006-02-01' AND
NEW.logdate < DATE '2006-03-01' ) THEN
INSERT INTO measurement_y2006m02 VALUES (NEW.*);
ELSIF ( NEW.logdate >= DATE '2006-03-01'AND
NEW.logdate < DATE '2006-04-01' ) THEN
INSERT INTO measurement_y2006m03 VALUES (NEW.*);
ELSIF ( NEW.logdate >= DATE '2006-04-01'AND
NEW.logdate < DATE '2006-05-01' ) THEN
INSERT INTO measurement_y2006m04 VALUES (NEW.*);
ELSIF ( NEW.logdate >= DATE '2006-05-01'AND
NEW.logdate < DATE '2006-06-01' ) THEN
INSERT INTO measurement_y2006m05 VALUES (NEW.*);
ELSIF ( NEW.logdate >= DATE '2006-06-01'AND
NEW.logdate < DATE '2006-07-01' ) THEN
INSERT INTO measurement_y2006m06 VALUES (NEW.*);
ELSIF ( NEW.logdate >= DATE '2006-07-01'AND
NEW.logdate < DATE '2006-08-01' ) THEN
INSERT INTO measurement_y2006m07 VALUES (NEW.*);
ELSIF ( NEW.logdate >= DATE '2006-08-01'AND
NEW.logdate < DATE '2006-09-01' ) THEN
INSERT INTO measurement_y2006m08 VALUES (NEW.*);
ELSIF ( NEW.logdate >= DATE '2006-09-01' AND
NEW.logdate < DATE '2006-10-01' ) THEN
INSERT INTO measurement_y2006m09 VALUES (NEW.*);
ELSIF ( NEW.logdate >= DATE '2006-10-01' AND
NEW.logdate < DATE '2006-11-01' ) THEN
INSERT INTO measurement_y2006m10 VALUES (NEW.*);
ELSIF ( NEW.logdate >= DATE '2006-11-01'AND
NEW.logdate < DATE '2006-12-01' ) THEN
INSERT INTO measurement_y2006m11 VALUES (NEW.*);
ELSIF ( NEW.logdate >= DATE '2006-12-01' AND
NEW.logdate < DATE '2007-01-01' ) THEN
INSERT INTO measurement_y2006m12 VALUES (NEW.*);
ELSE
RAISE EXCEPTION 'Date out of range. Fix the measurement_insert_trigger() function!';
END IF;
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
CREATE FUNCTION
说明:如果不想丢失数据,上面的ELSE 条件可以改成 INSERTINTO measurement _error_ logdate VALUES (NEW.*); 同时需要创建一张结构和measurement 一样的表measurement_error_logdate,这样,错误的logdate 数据就可以插入到这张表中而不是报错了。
1.5. 创建触发器
CREATE TRIGGERinsert_measurement_trigger
BEFORE INSERT ON measurement
FOR EACH ROW EXECUTE PROCEDUREmeasurement_insert_trigger();
CREATE TRIGGER
1.6. 改用RULE规则
也可以不用触发器,改用RULE规则,为每个分表创建规则
CREATE RULE measurement_y2006m01 AS
ON INSERT TO measurement where(NEW.logdate >= DATE '2006-01-01' AND
NEW.logdate < DATE'2006-02-01')
DO INSTEAD
INSERT INTO measurement VALUES (NEW.*);
CREATE RULE measurement_y2006m02 AS
ON INSERT TO measurement where(NEW.logdate >= DATE '2006-02-01' AND
NEW.logdate < DATE'2006-03-01')
DO INSTEAD
INSERT INTO measurement VALUES (NEW.*);
……省略
2 测试
2.1. 查看所有表
mydb=# \d
List of relations
Schema | Name | Type | Owner
--------+----------------------+-------+-------
public | measurement | table | super
public | measurement_y2006m01 | table | super
public | measurement_y2006m02 | table | super
public | measurement_y2006m03 | table | super
public | measurement_y2006m04 | table | super
public | measurement_y2006m05 | table | super
public | measurement_y2006m06 | table | super
public | measurement_y2006m07 | table | super
public | measurement_y2006m08 | table | super
public | measurement_y2006m09 | table | super
public | measurement_y2006m10 | table | super
public | measurement_y2006m11 | table | super
public | measurement_y2006m12 | table | super
(13rows)
2.2. 查看主表结构
mydb=#\d measurement
Table "public.measurement"
Column | Type | Modifiers
-----------+---------+-----------
city_id | integer | not null
logdate | date |not null
peaktemp | integer |
unitsales | integer |
Triggers:
insert_measurement_trigger BEFORE INSERT ON measurement FOR EACH ROWEXECUTE PROCEDURE measurement_insert_trigger().
Number of child tables: 12 (Use \d+ to listthem.)
2.3. 插入数据
mydb=# insert into measurement values(1,date '2006-02-10',1,1);
INSERT 0 0
mydb=# insert into measurement values(1,date '2006-03-10',1,1);
INSERT 0 0
mydb=# insert into measurement values(1,date '2006-04-10',1,1);
INSERT 0 0
2.4. 查看主表数据
mydb=# select * from measurement;
city_id | logdate | peaktemp | unitsales
---------+------------+----------+-----------
1 | 2006-02-10 | 1 | 1
1 | 2006-03-10 | 1 | 1
1 | 2006-04-10 | 1 | 1
(3 rows)
2.5. 查看分表数据
mydb=# select * frommeasurement_y2006m03;
city_id | logdate | peaktemp | unitsales
---------+------------+----------+-----------
1 | 2006-03-10 | 1 | 1
(1 row)
2.6. 分区排除和查询优化
默认情况下,是不会开启分区排除的,索引针对一个基于分区键条件的检索,要扫描所有的分区
mydb=# SET constraint_exclusion = off;
SET
mydb=# EXPLAIN SELECT count(*) FROMmeasurement WHERE logdate <= DATE '2006-02-01';
QUERYPLAN
-----------------------------------------------------------------------------------------------
Aggregate (cost=436.80..436.81 rows=1 width=0)
-> Append (cost=0.00..417.62 rows=7670 width=0)
-> Seq Scan onmeasurement (cost=0.00..32.12 rows=590width=0)
Filter: (logdate <='2006-02-01'::date)
-> Seq Scan onmeasurement_y2006m01 measurement (cost=0.00..32.12 rows=590 width=0)
Filter: (logdate <='2006-02-01'::date)
-> Seq Scan onmeasurement_y2006m02 measurement (cost=0.00..32.12 rows=590 width=0)
Filter: (logdate <='2006-02-01'::date)
-> Seq Scan onmeasurement_y2006m03 measurement (cost=0.00..32.12 rows=590 width=0)
Filter: (logdate <='2006-02-01'::date)
-> Seq Scan onmeasurement_y2006m04 measurement (cost=0.00..32.12 rows=590 width=0)
Filter: (logdate <='2006-02-01'::date)
-> Seq Scan onmeasurement_y2006m05 measurement (cost=0.00..32.12 rows=590 width=0)
Filter: (logdate <='2006-02-01'::date)
-> Seq Scan on measurement_y2006m06measurement (cost=0.00..32.12 rows=590width=0)
Filter: (logdate <='2006-02-01'::date)
-> Seq Scan onmeasurement_y2006m07 measurement (cost=0.00..32.12 rows=590 width=0)
Filter: (logdate <= '2006-02-01'::date)
-> Seq Scan onmeasurement_y2006m08 measurement (cost=0.00..32.12 rows=590 width=0)
Filter: (logdate <='2006-02-01'::date)
-> Seq Scan onmeasurement_y2006m09 measurement (cost=0.00..32.12 rows=590 width=0)
Filter: (logdate <='2006-02-01'::date)
-> Seq Scan onmeasurement_y2006m10 measurement (cost=0.00..32.12 rows=590 width=0)
Filter: (logdate <='2006-02-01'::date)
-> Seq Scan onmeasurement_y2006m11 measurement (cost=0.00..32.12 rows=590 width=0)
Filter: (logdate <='2006-02-01'::date)
-> Seq Scan onmeasurement_y2006m12 measurement (cost=0.00..32.12 rows=590 width=0)
Filter: (logdate <='2006-02-01'::date)
(28 rows)
2.7. 开启约束排除
mydb=# SET constraint_exclusion = on;
SET
mydb=> EXPLAIN SELECT count(*) FROM measurement WHERE logdate<= DATE '2006-02-01';
QUERYPLAN
-----------------------------------------------------------------------------------------------
Aggregate (cost=100.80..100.81 rows=1 width=0)
-> Append (cost=0.00..96.38 rows=1770 width=0)
-> Seq Scan on measurement (cost=0.00..32.12 rows=590 width=0)
Filter: (logdate <='2006-02-01'::date)
-> Seq Scan on measurement_y2006m01measurement (cost=0.00..32.12 rows=590width=0)
Filter:(logdate <= '2006-02-01'::date)
-> Seq Scan on measurement_y2006m02 measurement (cost=0.00..32.12 rows=590 width=0)
Filter:(logdate <= '2006-02-01'::date)
(8 rows)
至此分区表建立完成
postgresql 分区表创建及测试的更多相关文章
- PostgreSQL分区表实现——pg_pathman分区表管理
该博文用于自己学习记录,内容节选自: https://github.com/digoal/blog/blob/master/201610/20161024_01.md pg_pathman 创建分区表 ...
- MongoDB与PostgresQL无责任初步测试
PostgresQL一秒能插入多少条记录,MongoDB呢?读取的情况又如何?我写了一些简单的程序,得出了一些简单的数据,贴在这里分享,继续往下阅读前请注意下本文标题中的“无责任”,这表示此测试结果不 ...
- 通过arcgis在PostgreSQL中创建企业级地理数据库
部署环境: Win7 64位旗舰版 软件版本: PostgreSQL-9.1.3-2-windows-x64 Postgis-pg91x64-setup-2.0.6-1 Arcgis 10.1 SP1 ...
- 批量创建AD测试账号
在现场中,有时候客户会要求做一下AD压力测试,需要批量创建很多AD用户.奉献此代码供各位参考. 1: <# 2: 3: .DESCRIPTION 4: 批量创建AD测试账号 5: 6 ...
- soapui中文操作手册(二)----通过您的WSDL请求创建一个测试
1.通过您的WSDL请求创建一个测试 点击加号旁边的导航拓展项目树的Web服务,并选择请求: 在SoapUI Pro中,所述请求编辑出现在右边.SoapUI Pro有一个编辑器,它简化了XML的层 ...
- eos教程如何创建eos测试账号并且使用scatter插件
EOS代币租赁平台 --- Chintai平台已经在Jungle测试网络上部署了,欢迎大家来体验. 地址见: Chintai 公测版 官网是: Chintai 目前测试网络上面需要用到Scatter插 ...
- 用ArcMap在PostgreSQL中创建要素类需要执行”create enterprise geodatabase”吗
问:用Acmap在PostgreSQL中创建要素类需要执行"create enterprise geodatabase"吗? 关于这个问题,是在为新员工做postgresql培训后 ...
- 3)创建,测试,发布 第一个NET CORE程序
工具:Visual Studio Code 或者 Visual Studio 环境:.NET CORE 2.0 VS Code很强大 当然支持netcore的开发,但是我还是选择更熟悉更强大的VS. ...
- PostgreSQL SERIAL创建自增列
PostgreSQL SERIAL创建自增列 本文我们介绍PostgreSQL SERIAL,并展示如何使用serial类型创建表自增列. PostgreSQL SERIAL伪类型 PostgreSQ ...
随机推荐
- asp.net下ajax.ajaxMethod使用方法
使用AjaxMethod可以在客户端异步调用服务端方法,简单地说就是在JS里调用后台.cs文件里的方法,做一些JS无法做到的操作,如查询数据库. 使用AjaxMethod要满足一下几点: 1.如果 ...
- ASP.NET MVC4 部分视图
ASP.NET MVC4 部分视图 2014-10-24 16:48 by 易code, 2662 阅读, 1 评论, 收藏, 编辑 [部分视图] ASP.NET MVC 里的部分视图,相当于 Web ...
- NSString length的坑。
说坑,可能过头了,是我理所当然的把OC看作C了, char* cstr = "zh中文12"; NSString* s = [NSString stringWithUTF8Stri ...
- dos.orm学习地址
os.ORM(原Hxj.Data)于2009年发布.2015年正式开源,该组件已在数百个成熟项目中应用,是目前国内.Net用户量最多.最活跃.最完善的国产ORM.初期开发过程参考了NBear与MySo ...
- Validform自定义提示效果-使用自定义弹出框
$(function(){ $.Tipmsg.r=null; $("#add").Validform({ tiptype:function(msg){ layer.msg(msg) ...
- 神奇的Noip模拟试题 T3 科技节 位运算
3 科技节 (scifest.pas/.c/.cpp) [问题描述] 一年一度的科技节即将到来.同学们报名各项活动的名单交到了方克顺校长那,结果校长一看皱了眉头:这帮学生热情竟然如此高涨,每个人都报那 ...
- EditorLineEnds.ttr 错误问题
安装 Windows Write Live,在线安装,会先安装一个什么补丁,中途提示失败. 运行Delphi2007,第一次成功,第二次就是 EditorLineEnds.ttr文件错误. http: ...
- 在shell脚本中使用函数
转载请标明:http://www.cnblogs.com/winifred-tang94/ 对于在脚本中重复使用的功能模块,可以封装成为函数. shell脚本中函数的定义可以使用如下两种方式: a. ...
- [网络技术]网关 路由器 OSI
tracert 1.网关与路由 关键的区别:网关是这样一个网络节点:以两个不同协议搭建的网络可以通过它进行通信.路由器是这样一种设备:它能在计算机网络间收发数据包,同时创建一个覆盖网络(overlay ...
- java批量插入数据进数据库中
方式1: for循环,每一次进行一次插入数据. 方式2: jdbc的preparedStatement的batch操作 PreparedStatement.addBatch(); ...... Pre ...