示例讲解PostgreSQL表分区的三种方式
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了示例讲解PostgreSQL表分区的三种方式相关的知识,希望对你有一定的参考价值。
参考技术A 表分区是解决一些因单表过大引用的性能问题的方式,比如某张表过大就会造成查询变慢,可能分区是一种解决方案。一般建议当单表大小超过内存就可以考虑表分区了。PostgreSQL的表分区有三种方式:本文通过示例讲解如何进行这三种方式的分区。
为方便,我们通过Docker的方式启动一个PostgreSQL,可参考:《Docker启动PostgreSQL并推荐几款连接工具》。我们要选择较高的版本,否则不支持Hash分区,命令如下:
先创建一张表带有年龄,然后我们根据年龄分段来进行分区,创建表语句如下:
这个语句已经指定了按age字段来分区了,接着创建分区表:
这里创建了四张分区表,分别对应年龄是0到10岁、11到20岁、21到30岁、30岁以上。
接着我们插入一些数据:
可以看到这里的表名还是 pkslow_person_r ,而不是具体的分区表,说明对于客户端是无感知的。
我们查询也一样的:
但实际上是有分区表存在的:
而且分区表与主表的字段是一致的。
查询分区表,就只能查到那个特定分区的数据了:
类似的,列表分区是按特定的值来分区,比较某个城市的数据放在一个分区里。这里不再给出每一步的讲解,代码如下:
当我们查询第一个分区的时候,只有广州的数据:
哈希分区是指按字段取哈希值后再分区。具体的语句如下:
可以看到创建分区表的时候,我们用了取模的方式,所以如果要创建N个分区表,就要取N取模。
随便查询一张分区表如下:
可以看到同是SZ的哈希值是一样的,肯定会分在同一个分区,而BJ的哈希值取模后也属于同一个分区。
本文讲解了PostgreSQL分区的三种方式。
代码请查看:https://github.com/LarryDpk/pkslow-samples
postgresql----表分区
--下面的描述不记得在哪里抄来的了?!
表分区就是把逻辑上一个大表分割成物理上的多个小块,表分区可提供如下若干好处:
1.某些类型的查询性能可以得到极大提升。
2.更新的性能可以得到提升,因为表的每块索引要比整个数据集上的索引要小,如果索引不能全部放在内存里,那么在索引上的读写都会产生磁盘访问。
3.批量删除可以用简单的删除某个分区
4.将很少使用的数据移动到便宜的慢一些的存储介质上。
示例1.
1.创建主表
create table tbl_inherits_test ( a int, b timestamp without time zone ); create index idx_tbl_inherits_test_b on tbl_inherits_test using btree (b);
2.创建触发器函数,在INSERT父表时根据时间字段b写入时间b的分表,如果分表b不存在,则创建分表b,然后再INSERT分表
create or replace function f_insert_tbl_inherits_test() returns trigger as $body$ declare tablename varchar(32) default ‘‘; begin tablename=‘tbl_inherits_test_‘||to_char(NEW.b,‘YYYY_MM_DD‘); execute ‘insert into ‘||tablename||‘(a,b) values(‘||NEW.a||‘,‘‘‘||NEW.b||‘‘‘)‘;
return null;
EXCEPTION when undefined_table then execute ‘create table ‘||tablename||‘() inherits (tbl_inherits_test)‘; execute ‘create index idx_‘||tablename||‘_b on ‘||tablename||‘ using btree(b)‘; execute ‘insert into ‘||tablename||‘(a,b) values(‘||NEW.a||‘,‘‘‘||NEW.b||‘‘‘)‘; return null; end; $body$ language plpgsql;
3.创建触发器,当INSERT主表时执行触发器函数
create trigger trg_insert_tbl_inherits_test before insert on tbl_inherits_test for each row execute procedure f_insert_tbl_inherits_test();
4.向主表写数据验证结果
test=#insert into tbl_inherits_test(a,b) values(1,‘2016-06-20 17:40:21‘); test=# \d+ tbl_inherits_test Table "public.tbl_inherits_test" Column | Type | Modifiers | Storage | Stats target | Description --------+-----------------------------+-----------+---------+--------------+------------- a | integer | | plain | | b | timestamp without time zone | | plain | | Indexes: "idx_tbl_inherits_test_b" btree (b) Triggers: trg_insert_tbl_inherits_test BEFORE INSERT ON tbl_inherits_test FOR EACH ROW EXECUTE PROCEDURE f_insert_tbl_inherits_test() Child tables: tbl_inherits_test_2016_06_20
5.结果显示INSERT主表时会根据INSERT的数据b(2016-06-20 17:40:21)自动创建一个分表tbl_inherits_test_2016_06_20,再写入几条数据,查看结果
test=# insert into tbl_inherits_test(a,b) values (2,‘2016-06-20 08:08:08‘),(3,‘2016-06-21 19:00:00‘); INSERT 0 0 test=# \d+ tbl_inherits_test Table "public.tbl_inherits_test" Column | Type | Modifiers | Storage | Stats target | Description --------+-----------------------------+-----------+---------+--------------+------------- a | integer | | plain | | b | timestamp without time zone | | plain | | Indexes: "idx_tbl_inherits_test_b" btree (b) Triggers: trg_insert_tbl_inherits_test BEFORE INSERT ON tbl_inherits_test FOR EACH ROW EXECUTE PROCEDURE f_insert_tbl_inherits_test() Child tables: tbl_inherits_test_2016_06_20, tbl_inherits_test_2016_06_21
6.分别查询主表和分表的数据,直接查询主表会查询到所有分表的数据,但是使用only查询主表发现,主表中并没有数据(因为触发器函数中返回的是null)
test=# select * from tbl_inherits_test_2016_06_20 ; a | b ---+--------------------- 1 | 2016-06-20 17:40:21 2 | 2016-06-20 08:08:08 (2 rows) test=# select * from tbl_inherits_test_2016_06_21 ; a | b ---+--------------------- 3 | 2016-06-21 19:00:00 (1 row) test=# test=# select * from tbl_inherits_test ; a | b ---+--------------------- 1 | 2016-06-20 17:40:21 2 | 2016-06-20 08:08:08 3 | 2016-06-21 19:00:00 (3 rows) test=# select * from only tbl_inherits_test ; a | b ---+--- (0 rows)
以上是关于示例讲解PostgreSQL表分区的三种方式的主要内容,如果未能解决你的问题,请参考以下文章