相关文章推荐
胡子拉碴的斑马  ·  [Basic] Qt Notes - 知乎·  1 年前    · 
千杯不醉的仙人球  ·  smtp relay server ...·  1 年前    · 
逼格高的蜡烛  ·  How do I send and ...·  1 年前    · 

PostgreSQL 12 新增三个分区查询函数,如下:

  • pg_partition_tree(regclass): 返回分区表详细信息,例如分区名称、上一级分区名称、是否叶子结点、层级,层级 0 表示顶层父表。
  • pg_partition_ancestors(regclass): 返回上层分区名称,包括本层分区名称。
  • pg_partition_root(regclass): 返回顶层父表名称。
  • Add partition introspection functions (Michaël Paquier, Álvaro Herrera, Amit Langote)

    New function pg_partition_root() returns the top-most parent of a partition tree, pg_partition_ancestors() reports all ancestors of a partition, and pg_partition_tree() displays information about partitions.

    环境准备: 创建二维分区表

    创建父表,如下:

    CREATE TABLE userinfo (
     userid    int4,
     username  character varying(64),
     ctime   timestamp(6) without time zone
    ) PARTITION BY HASH(userid);

    创建第一层分区,如下:

    CREATE TABLE userinfo_p0 PARTITION OF userinfo FOR VALUES WITH(MODULUS 4, REMAINDER 0) PARTITION BY RANGE(ctime);
    CREATE TABLE userinfo_p1 PARTITION OF userinfo FOR VALUES WITH(MODULUS 4, REMAINDER 1);
    CREATE TABLE userinfo_p2 PARTITION OF userinfo FOR VALUES WITH(MODULUS 4, REMAINDER 2);
    CREATE TABLE userinfo_p3 PARTITION OF userinfo FOR VALUES WITH(MODULUS 4, REMAINDER 3);

    创建第二层分区,如下:

    CREATE TABLE userinfo_p0_old PARTITION OF userinfo_p0 FOR VALUES FROM (MINVALUE) TO ('2019-06-01');
    CREATE TABLE userinfo_p0_201906 PARTITION OF userinfo_p0 FOR VALUES FROM ('2019-06-01') TO ('2019-07-01');
    CREATE TABLE userinfo_p0_201907 PARTITION OF userinfo_p0 FOR VALUES FROM ('2019-07-01') TO ('2019-08-01');

    使用元命令查看分区表信息,如下:

    mydb=> \d+ userinfo
                                            Partitioned table "pguser.userinfo"
      Column  |              Type              | Collation | Nullable | Default | Storage  | Stats target | Description 
    ----------+--------------------------------+-----------+----------+---------+----------+--------------+-------------
     userid   | integer                        |           |          |         | plain    |              | 
     username | character varying(64)          |           |          |         | extended |              | 
     ctime    | timestamp(6) without time zone |           |          |         | plain    |              | 
    Partition key: HASH (userid)
    Partitions: userinfo_p0 FOR VALUES WITH (modulus 4, remainder 0), PARTITIONED,
                userinfo_p1 FOR VALUES WITH (modulus 4, remainder 1),
                userinfo_p2 FOR VALUES WITH (modulus 4, remainder 2),
                userinfo_p3 FOR VALUES WITH (modulus 4, remainder 3)
    

    备注:以上可以查看到分区表大部分信息,但二级分区的信息并没有显示,userinfo_p0 这行只显示 PARTITIONED,没有列出二级分区信息。

    若想查看二级分区信息,如下:

    mydb=> \d+ userinfo_p0
                                           Partitioned table "pguser.userinfo_p0"
      Column  |              Type              | Collation | Nullable | Default | Storage  | Stats target | Description 
    ----------+--------------------------------+-----------+----------+---------+----------+--------------+-------------
     userid   | integer                        |           |          |         | plain    |              | 
     username | character varying(64)          |           |          |         | extended |              | 
     ctime    | timestamp(6) without time zone |           |          |         | plain    |              | 
    Partition of: userinfo FOR VALUES WITH (modulus 4, remainder 0)
    Partition constraint: satisfies_hash_partition('16432'::oid, 4, 0, userid)
    Partition key: RANGE (ctime)
    Partitions: userinfo_p0_201906 FOR VALUES FROM ('2019-06-01 00:00:00') TO ('2019-07-01 00:00:00'),
                userinfo_p0_201907 FOR VALUES FROM ('2019-07-01 00:00:00') TO ('2019-08-01 00:00:00'),
                userinfo_p0_old FOR VALUES FROM (MINVALUE) TO ('2019-06-01 00:00:00')  

    pg_partition_tree 函数

    使用 pg_partition_tree() 函数查看分区表信息,如下:

    mydb=>  SELECT * FROM pg_partition_tree('userinfo');
           relid        | parentrelid | isleaf | level 
    --------------------+-------------+--------+-------
     userinfo           |             | f      |     0
     userinfo_p0        | userinfo    | f      |     1
     userinfo_p1        | userinfo    | t      |     1
     userinfo_p2        | userinfo    | t      |     1
     userinfo_p3        | userinfo    | t      |     1
     userinfo_p0_201906 | userinfo_p0 | t      |     2
     userinfo_p0_201907 | userinfo_p0 | t      |     2
     userinfo_p0_old    | userinfo_p0 | t      |     2
    (8 rows)

    备注: pg_partition_tree() 函数列出了分区表的所有分区、上一级分区、是否是叶子节点、当前分区所处层级信息。

    pg_partition_ancestors 函数

    pg_partition_ancestors 函数返回上层分区名称,包括本层分区名称,如下:

    mydb=> SELECT pg_partition_ancestors('userinfo_p0');
     pg_partition_ancestors 
    ------------------------
     userinfo_p0
     userinfo
    (2 rows)

    pg_partition_root 函数

    pg_partition_root()函数返回最顶层父表名称,如下:

    mydb=> SELECT pg_partition_root('userinfo_p0_201907');
     pg_partition_root 
    -------------------
     userinfo
    (1 row)

    验证数据分布

    最后验证二维分区表 userinfo 数据分布,插入测试数据,如下:

    INSERT INTO userinfo(userid,username,ctime) SELECT n, n || '_username',now() FROM generate_series(1,8) n;
    INSERT INTO userinfo(userid,username,ctime) SELECT n, n || '_username',now() - interval ' 2 months 'FROM generate_series(1,8) n;

    验证数据分布,如下:

    mydb=> \dt+ userinfo*
                                      List of relations
     Schema |        Name        |       Type        | Owner  |    Size    | Description 
    --------+--------------------+-------------------+--------+------------+-------------
     pguser | userinfo           | partitioned table | pguser | 0 bytes    | 
     pguser | userinfo_p0        | partitioned table | pguser | 0 bytes    | 
     pguser | userinfo_p0_201906 | table             | pguser | 8192 bytes | 
     pguser | userinfo_p0_201907 | table             | pguser | 0 bytes    | 
     pguser | userinfo_p0_old    | table             | pguser | 8192 bytes | 
     pguser | userinfo_p1        | table             | pguser | 8192 bytes | 
     pguser | userinfo_p2        | table             | pguser | 8192 bytes | 
     pguser | userinfo_p3        | table             | pguser | 8192 bytes | 
    (8 rows)

    根据表大小初步判读仅底层分区存储数据。

    查看二级分区数据分布上,如下:

    mydb=> SELECT * FROM userinfo_p0;
     userid |  username  |           ctime            
    --------+------------+----------------------------
          1 | 1_username | 2019-05-16 09:36:18.83122
          1 | 1_username | 2019-07-16 09:36:18.825426
    (2 rows)

    查看三级分区数据分布,如下:

    mydb=> SELECT * FROM userinfo_p0_201907;
     userid |  username  |           ctime            
    --------+------------+----------------------------
          1 | 1_username | 2019-07-16 09:36:18.825426
    (1 row)
    mydb=> SELECT * FROM userinfo_p0_201906;
     userid | username | ctime 
    --------+----------+-------
    (0 rows)
    mydb=> SELECT * FROM userinfo_p0_old;
     userid |  username  |           ctime           
    --------+------------+---------------------------
          1 | 1_username | 2019-05-16 09:36:18.83122

    对于一维分区表,PostgreSQL 提供的元命令足够查看分区的完整信息,但对于多维分区表,元命令无法查看详尽的分区信息,PostgreSQL 12 提供的分区函数很容易做到这点。

    尽管二维分区表的使用并不是很多,分区表函数提供了分区表查询的另一种途径。

  • Waiting for PostgreSQL 12 – Add pg_partition_tree to display information about partitions
  • Postgres 12 highlight - Functions for partitions
  • 最后推荐和张文升共同编写的《PostgreSQL实战》,本书基于PostgreSQL 10 编写,共18章,重点介绍SQL高级特性、并行查询、分区表、物理复制、逻辑复制、备份恢复、高可用、性能优化、PostGIS等,涵盖大量实战用例!

    链接:https://item.jd.com/12405774.html

    PostgreSQL 计算字符串字符数函数(CHAR_LENGTH(str))和字符串长度函数(LENGTH(str))
    PostgreSQL 计算字符串字符数函数(CHAR_LENGTH(str))和字符串长度函数(LENGTH(str))
    阿里云rds并发性能解读-大分区表高并发性能提升100倍?
    Redis读写分离实例的原理是:key统一写入到master,然后通过主从复制同步到slave,用户的请求通过proxy做判断,如果是写请求,转发到master;如果是读请求,分散转发到slave,这种架构适合读请求数量远大于写请求数量的业务
    PostgreSQL 普通表在线转换为分区表 - online exchange to partition table
    PostgreSQL 普通表在线转换为分区表 - online exchange to partition table
    大分区表高并发性能提升100倍?阿里云 RDS PostgreSQL 12 特性解读
    世界上几乎最强大的开源数据库系统 PostgreSQL,于 2019 年 10 月 3 日发布了 12 版本,该版本已经在阿里云正式发布。PostgreSQL 12 在功能和性能上都有很大提升,如大分区表高并发性能提升百倍,B-tree 索引空间和性能优化,实现 SQL 2016 标准的 JSON 特性,支持多列 MCV(Most-Common-Value)统计,内联 CTE(Common table expressions)以及可插拔的表存储访问接口等。本文对部分特性进行解读。
    PostgreSQL9.6支持基本表的分区。这部分将描述为什么以及如何来实现表分区作为你数据库设计的一部分。 概述 分区指的是将逻辑上一的一个大表分成多个小的物理上的片(子表),分区可以提供以下好处: .在某些情况下查询性能能够显著提升,特别是当那些访问压力大的行在一个分区或者少数几个分区时。 Pg提供相关行列转换函数string_agg和regexp_split_to_table。行转列:string_agg postgres=# select * from test.