--对于分区表constraint_exclusion 这个参数需要配置为partition或on
postgres=# show constraint_exclusion ;
constraint_exclusion
----------------------
partition --创建父子表, 用于存储分区数据
create table t(id int primary key);
create table t1(like t including all) inherits(t);
create table t2(like t including all) inherits(t);
create table t3(like t including all) inherits(t);
create table t4(like t including all) inherits(t);
--PostgreSQL的子表和子表之间的约束是没有任何关系的, 所以也可以有重叠, 即非全局约束.
alter table t1 add constraint ck_t1_1 check(id<0);
alter table t2 add constraint ck_t2_1 check(id>=0 and id<100);
alter table t3 add constraint ck_t3_1 check(id>=100 and id<200);
alter table t4 add constraint ck_t4_1 check(id>=200); --分区字段传入常量, 执行时扫描的是父表和约束对应的子表 :
postgres=# explain select * from t where id=10;
QUERY PLAN
-----------------------------------------------------------------------------
Append (cost=0.00..8.17 rows=2 width=4)
-> Seq Scan on t (cost=0.00..0.00 rows=1 width=4)
Filter: (id = 10)
-> Index Only Scan using t2_pkey on t2 (cost=0.15..8.17 rows=1 width=4)
Index Cond: (id = 10)
(5 rows) --分区字段传入常量, 执行时扫描的是父表和约束对应的子表;
postgres=# prepare p_test as select * from t where id=$1;
PREPARE
postgres=# explain execute p_test(1);
QUERY PLAN
-----------------------------------------------------------------------------
Append (cost=0.00..8.17 rows=2 width=4)
-> Seq Scan on t (cost=0.00..0.00 rows=1 width=4)
Filter: (id = 1)
-> Index Only Scan using t2_pkey on t2 (cost=0.15..8.17 rows=1 width=4)
Index Cond: (id = 1)
(5 rows) --子句查询, 执行时扫描的是父表和所有子表, 注意这里使用的子查询是子表的查询, 理论上应该是扫描父表和该子表
postgres=# explain select * from t where id=(select id from t1 limit 1);
QUERY PLAN
-----------------------------------------------------------------------------
Append (cost=0.01..32.70 rows=5 width=4)
InitPlan 1 (returns $0)
-> Limit (cost=0.00..0.01 rows=1 width=4)
-> Seq Scan on t1 t1_1 (cost=0.00..34.00 rows=2400 width=4)
-> Seq Scan on t (cost=0.00..0.00 rows=1 width=4)
Filter: (id = $0)
-> Index Only Scan using t1_pkey on t1 (cost=0.15..8.17 rows=1 width=4)
Index Cond: (id = $0)
-> Index Only Scan using t2_pkey on t2 (cost=0.15..8.17 rows=1 width=4)
Index Cond: (id = $0)
-> Index Only Scan using t3_pkey on t3 (cost=0.15..8.17 rows=1 width=4)
Index Cond: (id = $0)
-> Index Only Scan using t4_pkey on t4 (cost=0.15..8.17 rows=1 width=4)
Index Cond: (id = $0)
(14 rows) --综上可知在对分区表进行查询时最好使用字面常量,而不要使用子查询之类复杂的sql --如果子表上约束删除,则pg不得不把删除约束的子表也加入到查询中(即使子表可以忽略)
alter table t4 drop constraint ck_t4_1;
postgres=# explain select * from t where id=10;
QUERY PLAN
-----------------------------------------------------------------------------
Append (cost=0.00..16.34 rows=3 width=4)
-> Seq Scan on t (cost=0.00..0.00 rows=1 width=4)
Filter: (id = 10)
-> Index Only Scan using t2_pkey on t2 (cost=0.15..8.17 rows=1 width=4)
Index Cond: (id = 10)
-> Index Only Scan using t4_pkey on t4 (cost=0.15..8.17 rows=1 width=4)
Index Cond: (id = 10)
(7 rows) --如果constraint_exclusion设置为off,pg不得不进行全表扫描
postgres=# set constraint_exclusion=off;
SET
postgres=# explain select * from t where id=10;
QUERY PLAN
-----------------------------------------------------------------------------
Append (cost=0.00..32.69 rows=5 width=4)
-> Seq Scan on t (cost=0.00..0.00 rows=1 width=4)
Filter: (id = 10)
-> Index Only Scan using t1_pkey on t1 (cost=0.15..8.17 rows=1 width=4)
Index Cond: (id = 10)
-> Index Only Scan using t2_pkey on t2 (cost=0.15..8.17 rows=1 width=4)
Index Cond: (id = 10)
-> Index Only Scan using t3_pkey on t3 (cost=0.15..8.17 rows=1 width=4)
Index Cond: (id = 10)
-> Index Only Scan using t4_pkey on t4 (cost=0.15..8.17 rows=1 width=4)
Index Cond: (id = 10)
(11 rows) --分区表上一般针对分区建立相对应的分区索引
--建在父表的索引为全局索引,但如果你表没有数据要查询子表时,则分区表要进行全表扫描 --父表建立的全局索引
postgres=# \d+ p
Table "public.p"
Column | Type | Modifiers | Storage | Stats target | Description
-----------+--------------------------------+-----------+---------+--------------+-------------
city_id | integer | not null | plain | |
logtime | timestamp(0) without time zone | not null | plain | |
peaktemp | integer | | plain | |
unitsales | integer | | plain | |
Indexes:
"idx_city_id" btree (city_id)
"idx_p_logtime" btree (logtime)
Triggers:
delete_p_trigger BEFORE DELETE ON p FOR EACH ROW EXECUTE PROCEDURE p_delete_trigger()
insert_p_trigger BEFORE INSERT ON p FOR EACH ROW EXECUTE PROCEDURE p_insert_trigger()
Child tables: p_201201,
p_201202,
p_201203,
p_201204,
p_201205,
p_201206,
p_201207,
p_201208,
p_201209,
p_201210,
p_201211,
p_201212,
p_default
Has OIDs: no --分区没有索引,不能使用父表索引
postgres=# explain select * from p_201202 where city_id=2 and logtime=timestamp '2012-02-02 12:59:59';
QUERY PLAN
----------------------------------------------------------------------------------------------
Seq Scan on p_201202 (cost=0.00..214.01 rows=2 width=20)
Filter: ((city_id = 2) AND (logtime = '2012-02-02 12:59:59'::timestamp without time zone))
(2 rows) --建立分区索引,可以使用分区索引
postgres=# CREATE INDEX idx_p_201202_city_id ON p_201202 (city_id);
CREATE INDEX
postgres=# explain select * from p_201202 where city_id=2 and logtime=timestamp '2012-02-02 12:59:59';
QUERY PLAN
--------------------------------------------------------------------------------------
Index Scan using idx_p_201202_city_id on p_201202 (cost=0.29..8.33 rows=2 width=20)
Index Cond: (city_id = 2)
Filter: (logtime = '2012-02-02 12:59:59'::timestamp without time zone) --也可以指定只查询父表的数据 postgres=# select * from only p;
city_id | logtime | peaktemp | unitsales
---------+---------+----------+-----------
(0 rows) --如果一个分区表,父子表之间不再有继承关系,则查询父表时不再过滤到子表
postgres=# alter table t3 no inherit t;
ALTER TABLE
postgres=# explain select count(*) from t;
QUERY PLAN
------------------------------------------------------------------
Aggregate (cost=73.50..73.51 rows=1 width=0)
-> Append (cost=0.00..62.80 rows=4281 width=0)
-> Seq Scan on t (cost=0.00..0.00 rows=1 width=0)
-> Seq Scan on t1 (cost=0.00..31.40 rows=2140 width=0)
-> Seq Scan on t2 (cost=0.00..31.40 rows=2140 width=0)
(5 rows) --再次添加继承,查询父表可以过滤到子表
postgres=# alter table t3 inherit t;
ALTER TABLE
postgres=# explain select count(*) from t;
QUERY PLAN
------------------------------------------------------------------
Aggregate (cost=110.25..110.26 rows=1 width=0)
-> Append (cost=0.00..94.20 rows=6421 width=0)
-> Seq Scan on t (cost=0.00..0.00 rows=1 width=0)
-> Seq Scan on t1 (cost=0.00..31.40 rows=2140 width=0)
-> Seq Scan on t2 (cost=0.00..31.40 rows=2140 width=0)
-> Seq Scan on t3 (cost=0.00..31.40 rows=2140 width=0)
(6 rows) --以下为p表测试数据代码
CREATE TABLE p (
city_id int not null,
logtime timestamp(0) not null,
peaktemp int,
unitsales int
); CREATE INDEX idx_p_logtime ON p (logtime); CREATE TABLE p_201201 (LIKE p INCLUDING all) INHERITS (p);
CREATE TABLE p_201202 (LIKE p INCLUDING all) INHERITS (p);
CREATE TABLE p_201203 (LIKE p INCLUDING all) INHERITS (p);
CREATE TABLE p_201204 (LIKE p INCLUDING all) INHERITS (p);
CREATE TABLE p_201205 (LIKE p INCLUDING all) INHERITS (p);
CREATE TABLE p_201206 (LIKE p INCLUDING all) INHERITS (p);
CREATE TABLE p_201207 (LIKE p INCLUDING all) INHERITS (p);
CREATE TABLE p_201208 (LIKE p INCLUDING all) INHERITS (p);
CREATE TABLE p_201209 (LIKE p INCLUDING all) INHERITS (p);
CREATE TABLE p_201210 (LIKE p INCLUDING all) INHERITS (p);
CREATE TABLE p_201211 (LIKE p INCLUDING all) INHERITS (p);
CREATE TABLE p_201212 (LIKE p INCLUDING all) INHERITS (p);
CREATE TABLE p_default (LIKE p INCLUDING all) INHERITS (p); CREATE OR REPLACE FUNCTION p_insert_trigger()
RETURNS TRIGGER AS $$
BEGIN
IF ( NEW.logtime >= DATE '2012-01-01' AND NEW.logtime < DATE '2012-02-01' ) THEN
INSERT INTO p_201201 VALUES (NEW.*);
ELSIF ( NEW.logtime >= DATE '2012-02-01' AND NEW.logtime < DATE '2012-03-01' ) THEN
INSERT INTO p_201202 VALUES (NEW.*);
ELSIF ( NEW.logtime >= DATE '2012-03-01' AND NEW.logtime < DATE '2012-04-01' ) THEN
INSERT INTO p_201203 VALUES (NEW.*);
ELSIF ( NEW.logtime >= DATE '2012-04-01' AND NEW.logtime < DATE '2012-05-01' ) THEN
INSERT INTO p_201204 VALUES (NEW.*);
ELSIF ( NEW.logtime >= DATE '2012-05-01' AND NEW.logtime < DATE '2012-06-01' ) THEN
INSERT INTO p_201205 VALUES (NEW.*);
ELSIF ( NEW.logtime >= DATE '2012-06-01' AND NEW.logtime < DATE '2012-07-01' ) THEN
INSERT INTO p_201206 VALUES (NEW.*);
ELSIF ( NEW.logtime >= DATE '2012-07-01' AND NEW.logtime < DATE '2012-08-01' ) THEN
INSERT INTO p_201207 VALUES (NEW.*);
ELSIF ( NEW.logtime >= DATE '2012-08-01' AND NEW.logtime < DATE '2012-09-01' ) THEN
INSERT INTO p_201208 VALUES (NEW.*);
ELSIF ( NEW.logtime >= DATE '2012-09-01' AND NEW.logtime < DATE '2012-10-01' ) THEN
INSERT INTO p_201209 VALUES (NEW.*);
ELSIF ( NEW.logtime >= DATE '2012-10-01' AND NEW.logtime < DATE '2012-11-01' ) THEN
INSERT INTO p_201210 VALUES (NEW.*);
ELSIF ( NEW.logtime >= DATE '2012-11-01' AND NEW.logtime < DATE '2012-12-01' ) THEN
INSERT INTO p_201211 VALUES (NEW.*);
ELSIF ( NEW.logtime >= DATE '2012-12-01' AND NEW.logtime < DATE '2013-01-01' ) THEN
INSERT INTO p_201212 VALUES (NEW.*);
ELSIF ( NEW.logtime >= DATE '2013-01-01' OR NEW.logtime < DATE '2012-01-01' ) THEN
INSERT INTO p_default VALUES (NEW.*);
ELSE
RAISE EXCEPTION 'Date out of range. Fix the p_insert_trigger() function!';
END IF;
RETURN NULL;
END;
$$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION p_delete_trigger()
RETURNS TRIGGER AS $$
BEGIN
IF ( OLD.logtime >= DATE '2012-01-01' AND OLD.logtime < DATE '2012-02-01' ) THEN
DELETE FROM p_201201 WHERE logtime=OLD.logtime;
ELSIF ( OLD.logtime >= DATE '2012-02-01' AND OLD.logtime < DATE '2012-03-01' ) THEN
DELETE FROM p_201202 WHERE logtime=OLD.logtime;
ELSIF ( OLD.logtime >= DATE '2012-03-01' AND OLD.logtime < DATE '2012-04-01' ) THEN
DELETE FROM p_201203 WHERE logtime=OLD.logtime;
ELSIF ( OLD.logtime >= DATE '2012-04-01' AND OLD.logtime < DATE '2012-05-01' ) THEN
DELETE FROM p_201204 WHERE logtime=OLD.logtime;
ELSIF ( OLD.logtime >= DATE '2012-05-01' AND OLD.logtime < DATE '2012-06-01' ) THEN
DELETE FROM p_201205 WHERE logtime=OLD.logtime;
ELSIF ( OLD.logtime >= DATE '2012-06-01' AND OLD.logtime < DATE '2012-07-01' ) THEN
DELETE FROM p_201206 WHERE logtime=OLD.logtime;
ELSIF ( OLD.logtime >= DATE '2012-07-01' AND OLD.logtime < DATE '2012-08-01' ) THEN
DELETE FROM p_201207 WHERE logtime=OLD.logtime;
ELSIF ( OLD.logtime >= DATE '2012-08-01' AND OLD.logtime < DATE '2012-09-01' ) THEN
DELETE FROM p_201208 WHERE logtime=OLD.logtime;
ELSIF ( OLD.logtime >= DATE '2012-09-01' AND OLD.logtime < DATE '2012-10-01' ) THEN
DELETE FROM p_201209 WHERE logtime=OLD.logtime;
ELSIF ( OLD.logtime >= DATE '2012-10-01' AND OLD.logtime < DATE '2012-11-01' ) THEN
DELETE FROM p_201210 WHERE logtime=OLD.logtime;
ELSIF ( OLD.logtime >= DATE '2012-11-01' AND OLD.logtime < DATE '2012-12-01' ) THEN
DELETE FROM p_201211 WHERE logtime=OLD.logtime;
ELSIF ( OLD.logtime >= DATE '2012-12-01' AND OLD.logtime < DATE '2013-01-01' ) THEN
DELETE FROM p_201212 WHERE logtime=OLD.logtime;
ELSIF ( OLD.logtime >= DATE '2013-01-01' OR OLD.logtime < DATE '2012-01-01' ) THEN
DELETE FROM p_default WHERE logtime=OLD.logtime;
ELSE
RAISE EXCEPTION 'Date out of range. Fix the p_insert_trigger() function!';
END IF;
RETURN NULL;
END;
$$ LANGUAGE plpgsql; CREATE TRIGGER insert_p_trigger
BEFORE INSERT ON p
FOR EACH ROW EXECUTE PROCEDURE p_insert_trigger(); CREATE TRIGGER delete_p_trigger
BEFORE DELETE ON p
FOR EACH ROW EXECUTE PROCEDURE p_delete_trigger(); INSERT INTO p (city_id, logtime, peaktemp, unitsales) VALUES (1, timestamp '2012-01-02 12:59:59', 20, 10);
INSERT INTO p (city_id, logtime, peaktemp, unitsales) VALUES (2, timestamp '2012-02-02 12:59:59', 20, 10);
INSERT INTO p (city_id, logtime, peaktemp, unitsales) VALUES (3, timestamp '2012-03-02 12:59:59', 20, 10);
INSERT INTO p (city_id, logtime, peaktemp, unitsales) VALUES (4, timestamp '2012-04-02 12:59:59', 20, 10);
INSERT INTO p (city_id, logtime, peaktemp, unitsales) VALUES (5, timestamp '2012-05-02 12:59:59', 20, 10);
INSERT INTO p (city_id, logtime, peaktemp, unitsales) VALUES (6, timestamp '2012-06-02 12:59:59', 20, 10);
INSERT INTO p (city_id, logtime, peaktemp, unitsales) VALUES (7, timestamp '2012-07-02 12:59:59', 20, 10);
INSERT INTO p (city_id, logtime, peaktemp, unitsales) VALUES (8, timestamp '2012-08-02 12:59:59', 20, 10);
INSERT INTO p (city_id, logtime, peaktemp, unitsales) VALUES (9, timestamp '2012-09-02 12:59:59', 20, 10);
INSERT INTO p (city_id, logtime, peaktemp, unitsales) VALUES (10, timestamp '2012-10-02 12:59:59', 20, 10);
INSERT INTO p (city_id, logtime, peaktemp, unitsales) VALUES (11, timestamp '2012-11-02 12:59:59', 20, 10);
INSERT INTO p (city_id, logtime, peaktemp, unitsales) VALUES (12, timestamp '2012-12-02 12:59:59', 20, 10);
INSERT INTO p (city_id, logtime, peaktemp, unitsales) VALUES (13, timestamp '2013-01-02 12:59:59', 20, 10);
INSERT INTO p (city_id, logtime, peaktemp, unitsales) VALUES (14, timestamp '2011-12-02 12:59:59', 20, 10); INSERT INTO p (city_id, logtime, peaktemp, unitsales) select m, timestamp '2012-02-02 12:59:59', 20, 10 from generate_series(1,10000) m; explain select * from p_201202 where city_id=2 and logtime=timestamp '2012-02-02 12:59:59';
转载:https://yq.aliyun.com/articles/2637?spm=5176.100240.searchblog.12.59Jibq#

转载:postgresql分区与优化的更多相关文章

  1. PostgreSQL之性能优化(转)

    转载自:https://blog.csdn.net/huangwenyi1010/article/details/72853785 解决问题 前言 PostgreSQL的配置参数作为性能调优的一部分, ...

  2. PostgreSQL 分区索引演进

    PostgreSQL 分区表,操作性相当便捷. 但只能在创建时决定是否为分区表,并决定分区条件字段,普通表创建后,不能在修改为分区表. Note:通过其他方法也可转化为分区表. 和其他数据库一样,分区 ...

  3. 【转载】PHP性能优化干货

    PHP优化对于PHP的优化主要是对php.ini中的相关主要参数进行合理调整和设置,以下我们就来看看php.ini中的一些对性能影响较大的参数应该如何设置. # vi /etc/php.ini (1) ...

  4. 【转载】 Spark性能优化指南——基础篇

    转自:http://tech.meituan.com/spark-tuning-basic.html?from=timeline 前言 开发调优 调优概述 原则一:避免创建重复的RDD 原则二:尽可能 ...

  5. 【转载】MySQL性能优化的最佳20+条经验

    今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显.关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我们程序员需要去关注的事情.当我们去设计数据库表结构,对操作数据 ...

  6. [转载]U3d常规性能优化技巧

    以下技巧并不是必须的,但是对于想要提升游戏性能的人来说应该还是很不错的. 优化的常规技巧 n 剖析你的游戏. 不要花费时间来优化那些晦涩的代码或者缩减图形文件的大小,除非这是你游戏的瓶颈.第一次剖析你 ...

  7. 转载 50种方法优化SQL Server数据库查询

    原文地址 http://www.cnblogs.com/zhycyq/articles/2636748.html 50种方法优化SQL Server数据库查询 查询速度慢的原因很多,常见如下几种: 1 ...

  8. 【转载】 Spark性能优化:资源调优篇

    在开发完Spark作业之后,就该为作业配置合适的资源了.Spark的资源参数,基本都可以在spark-submit命令中作为参数设置.很多Spark初学者,通常不知道该设置哪些必要的参数,以及如何设置 ...

  9. PostgreSQL查询优化逻辑优化之其他

    上一节我们介绍了PostgreSQL的子查询优化,子查询优化把一部分可以优化的子查询上拉到主查询成为join. preprocess_expression 将表达式(目标列,where,join,ha ...

随机推荐

  1. 你不一定懂的cpu显示信息

    在linux命令中用top查看系统的情况,在cpu这一行有一些分部表示什么 下面有一篇博文,对此写的非常清楚,特转载.猛击下面的链接 http://www.cnblogs.com/yjf512/p/3 ...

  2. Java基础知识笔记(二:泛型和枚举)

    1.泛型 与面向对象的多态性相类似,应用泛型可以提高程序的复用性.与多态性不同的是,应用泛型可以减少数据的类型转换,从而提高代码的运行效率.泛型实际上是通过给类或接口增加类型参数实现的.不带泛型的类的 ...

  3. WPFTookit Chart 高级进阶

    数据源增加SeriesSource 使用方式 <Charting:Chart x:Name="chart" Helper:ChartHelper.DependentValue ...

  4. VB.NET中图像处理的一些技巧以及其和C#图像处理的差距。

    早期的时候我使用的开发工具是VB6,VB6做图像处理的速度在我的软件Imageshop中有所体现,还是算可以的.目前,我已经改用C#来研究图像算法,C#中有指针,做图像处理起来效率确实要高不少.VB. ...

  5. hdu-5988 Coding Contest(费用流)

    题目链接: Coding Contest Time Limit: 2000/1000 MS (Java/Others)     Memory Limit: 65536/65536 K (Java/Ot ...

  6. MySQL的基本知识 -- 命令

    1.数据库和表 SHOW DATABASES; 返回可用数据库的一个列表 SHOW TABLES; 返回一个数据库内的表的列表 SHOW COLUMNS FROM tableName; 返回数据表的表 ...

  7. nginx下目录浏览及其验证功能配置记录

    工作中常常有写不能有网页下载东西的需求,在Apache下搭建完成后直接导入文件即可达到下载/显示文件的效果;而Nginx的目录列表功能默认是关闭的,如果需要打开Nginx的目录列表功能,需要手动配置, ...

  8. ES5基础之正则表达式01:初次见面

    1.正则初次见面 测试地址:https://regexper.com 第一个正则:匹配 2006-10-11 或 2006/10/11 var reg = /^\d{4}[-/]\d{2}[-/]\d ...

  9. C++学习笔记(1)

    本学习笔记是C++ primer plus(第六版)学习笔记.复习C++基础知识的可以瞄瞄. 转载请注明出处http://www.cnblogs.com/zrtqsk/p/3874148.html,谢 ...

  10. jQuery下拉框扩展和美化插件Chosen

    Chosen 是一个支持jquery的select下拉框美化插件,它能让丑陋的.很长的select选择框变的更好看.更方便.不仅如此,它更扩展了select,增加了自动筛选的功能.它可对列表进行分组, ...