postgresql 12 数据库分区表之 hash

os: centos 7.4
db: postgresql 12.2

postgresql 12 的分区表已经比较完善。

版本

# cat /etc/centos-release
CentOS Linux release 7.4.1708 (Core) 
# 
# su - postgres
Last login: Thu Mar 19 14:47:45 CST 2020 on pts/0
$ 
$ psql
psql (12.2)
Type "help" for help.

postgres=# select version();
                                                 version                                                 
---------------------------------------------------------------------------------------------------------
 PostgreSQL 12.2 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-39), 64-bit
(1 row)

postgres=# show enable_partition_pruning;
 enable_partition_pruning 
--------------------------
 on
(1 row)

postgres=# select name,setting from pg_settings where name like '%partition%';
               name                | setting 
-----------------------------------+---------
 enable_partition_pruning          | on
 enable_partitionwise_aggregate    | off
 enable_partitionwise_join         | off
(3 rows) 

single column hash

single column in the partition key

postgres=# CREATE TABLE orders (
    order_id     bigint not null,
    cust_id      bigint not null,
    status       text
) PARTITION BY HASH (order_id);

CREATE TABLE orders_1 PARTITION OF orders FOR VALUES WITH (MODULUS 4, REMAINDER 0);
CREATE TABLE orders_2 PARTITION OF orders FOR VALUES WITH (MODULUS 4, REMAINDER 1);
CREATE TABLE orders_3 PARTITION OF orders FOR VALUES WITH (MODULUS 4, REMAINDER 2);
CREATE TABLE orders_4 PARTITION OF orders FOR VALUES WITH (MODULUS 4, REMAINDER 3);

postgres=# \d+
                                       List of relations
 Schema |             Name              |       Type        |  Owner   |    Size    | Description 
--------+-------------------------------+-------------------+----------+------------+-------------
 public | orders                        | partitioned table | postgres | 0 bytes    | 
 public | orders_1                      | table             | postgres | 8192 bytes | 
 public | orders_2                      | table             | postgres | 8192 bytes | 
 public | orders_3                      | table             | postgres | 8192 bytes | 
 public | orders_4                      | table             | postgres | 8192 bytes | 
(5 rows)

postgres=# select * from pg_inherits;
 inhrelid | inhparent | inhseqno 
----------+-----------+----------
    16664 |     16661 |        1
    16671 |     16661 |        1
    16677 |     16661 |        1
    16683 |     16661 |        1
(4 rows)

postgres=# insert into orders
select id,
       id,
	   md5(id::text)
  from generate_series(1,100000) as id;

postgres=# \d+
                                        List of relations
 Schema |             Name              |       Type        |  Owner   |    Size    | Description 
--------+-------------------------------+-------------------+----------+------------+-------------
 public | orders                        | partitioned table | postgres | 0 bytes    | 
 public | orders_1                      | table             | postgres | 2112 kB    | 
 public | orders_2                      | table             | postgres | 2096 kB    | 
 public | orders_3                      | table             | postgres | 2096 kB    | 
 public | orders_4                      | table             | postgres | 2088 kB    | 
(5 rows)

postgres=# explain select * from orders where order_id=9;
                        QUERY PLAN                         
-----------------------------------------------------------
 Seq Scan on orders_2  (cost=0.00..570.23 rows=1 width=49)
   Filter: (order_id = 9)
(2 rows)

postgres=# explain select * from orders where order_id in (9,10);
                           QUERY PLAN                            
-----------------------------------------------------------------
 Append  (cost=0.00..1138.81 rows=4 width=49)
   ->  Seq Scan on orders_2  (cost=0.00..570.23 rows=2 width=49)
         Filter: (order_id = ANY ('{9,10}'::bigint[]))
   ->  Seq Scan on orders_4  (cost=0.00..568.56 rows=2 width=49)
         Filter: (order_id = ANY ('{9,10}'::bigint[]))
(5 rows)

postgres=# explain select * from orders where order_id between 199 and 202;
                           QUERY PLAN                            
-----------------------------------------------------------------
 Append  (cost=0.00..2533.04 rows=8 width=49)
   ->  Seq Scan on orders_1  (cost=0.00..636.89 rows=2 width=49)
         Filter: ((order_id >= 199) AND (order_id <= 202))
   ->  Seq Scan on orders_2  (cost=0.00..632.67 rows=2 width=49)
         Filter: ((order_id >= 199) AND (order_id <= 202))
   ->  Seq Scan on orders_3  (cost=0.00..632.57 rows=2 width=49)
         Filter: ((order_id >= 199) AND (order_id <= 202))
   ->  Seq Scan on orders_4  (cost=0.00..630.88 rows=2 width=49)
         Filter: ((order_id >= 199) AND (order_id <= 202))
(9 rows)

multiple columns hash

multiple columns in the partition key

postgres=# CREATE TABLE orders_his (
    order_id     bigint not null,
    cust_id      bigint not null,
    status       text
) PARTITION BY HASH (order_id,cust_id);

CREATE TABLE orders_his_1 PARTITION OF orders_his FOR VALUES WITH (MODULUS 4, REMAINDER 0);
CREATE TABLE orders_his_2 PARTITION OF orders_his FOR VALUES WITH (MODULUS 4, REMAINDER 1);
CREATE TABLE orders_his_3 PARTITION OF orders_his FOR VALUES WITH (MODULUS 4, REMAINDER 2);
CREATE TABLE orders_his_4 PARTITION OF orders_his FOR VALUES WITH (MODULUS 4, REMAINDER 3);

postgres=# \d+
                                       List of relations
 Schema |             Name              |       Type        |  Owner   |    Size    | Description 
--------+-------------------------------+-------------------+----------+------------+-------------
 public | orders_his                    | partitioned table | postgres | 0 bytes    | 
 public | orders_his_1                  | table             | postgres | 8192 bytes | 
 public | orders_his_2                  | table             | postgres | 8192 bytes | 
 public | orders_his_3                  | table             | postgres | 8192 bytes | 
 public | orders_his_4                  | table             | postgres | 8192 bytes | 
(5 rows)

postgres=# select * from pg_inherits;
 inhrelid | inhparent | inhseqno 
----------+-----------+----------
    16696 |     16693 |        1
    16702 |     16693 |        1
    16708 |     16693 |        1
    16714 |     16693 |        1
(4 rows)

postgres=# insert into orders_his
select id,
       id,
	   md5(id::text)
  from generate_series(1,200000) as id;

postgres=# \d+
                                        List of relations
 Schema |             Name              |       Type        |  Owner   |    Size    | Description 
--------+-------------------------------+-------------------+----------+------------+-------------
 public | orders_his                    | partitioned table | postgres | 0 bytes    | 
 public | orders_his_1                  | table             | postgres | 4168 kB    | 
 public | orders_his_2                  | table             | postgres | 4144 kB    | 
 public | orders_his_3                  | table             | postgres | 4160 kB    | 
 public | orders_his_4                  | table             | postgres | 4168 kB    | 
(5 rows)

postgres=# explain select * from orders_his where order_id=9;
                              QUERY PLAN                              
----------------------------------------------------------------------
 Append  (cost=0.00..4564.02 rows=4 width=49)
   ->  Seq Scan on orders_his_1  (cost=0.00..1142.81 rows=1 width=49)
         Filter: (order_id = 9)
   ->  Seq Scan on orders_his_2  (cost=0.00..1136.95 rows=1 width=49)
         Filter: (order_id = 9)
   ->  Seq Scan on orders_his_3  (cost=0.00..1140.99 rows=1 width=49)
         Filter: (order_id = 9)
   ->  Seq Scan on orders_his_4  (cost=0.00..1143.25 rows=1 width=49)
         Filter: (order_id = 9)
(9 rows)

postgres=# explain select * from orders_his where order_id=9 and cust_id=9;
                           QUERY PLAN                           
----------------------------------------------------------------
 Seq Scan on orders_his_2  (cost=0.00..1261.54 rows=1 width=49)
   Filter: ((order_id = 9) AND (cust_id = 9))
(2 rows)

参考:
https://www.postgresql.org/docs/12/sql-createtable.html
https://www.postgresql.org/docs/12/ddl-partitioning.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
PostgreSQL 支持分区,它允许将数据根据特定的条件拆分成多个子,从而提高查询性能和管理数据。下面是一些关于 PostgreSQL 分区的基本信息: 1. 分区定义:在创建时,可以使用 PARTITION BY 子句指定分区键。常见的分区键类型包括范围(range)、列(list)和哈希(hash)。 2. 范围分区(Range partitioning):根据某个列的值范围进行分区,例如按时间范围、按数值范围等。可以使用 CREATE TABLE 语句的 PARTITION OF 子句定义每个分区。 3. 列分区(List partitioning):根据某个列的值列进行分区,例如按地区、按部门等。也可以使用 CREATE TABLE 语句的 PARTITION OF 子句定义每个分区。 4. 哈希分区Hash partitioning):根据某个列的哈希值进行分区,通常用于数据平均分布的场景。使用 CREATE TABLE 语句的 PARTITION OF 子句定义每个分区。 5. 分区管理:分区可以通过 ALTER TABLE 添加或删除分区。还可以使用 EXCHANGE PARTITION 子句将数据从非分区或已有分区中交换进入分区。 6. 查询优化:PostgreSQL 的查询优化器会在执行查询时自动识别并只查询相关分区,从而提高查询性能。同时,可以通过查询约束来进一步减少查询的分区范围。 需要注意的是,分区数据库中的使用需要根据具体的业务需求和数据特点来决定,同时需要合理设计和规划分区键,以及考虑数据维护和查询优化等方面的因素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数据库人生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值