首页 > 其他分享 >Postgres分表

Postgres分表

时间:2024-04-23 18:44:05浏览次数:24  
标签:info control Postgres alarm varying character time 分表

这个需求就是一个典型的按时间创建分区表,首先看一下步骤:

  • 创建父表

先创建一张“父表”,所有分区表都从它继承,这个表中没有数据,也不要在这个表上定义任何检查约束及索引,现在我们就先创建这样一张表,但之前先建一个序列:

CREATE SEQUENCE "public"."control_alarm_info_uid_seq"

INCREMENT 1

MINVALUE 1

MAXVALUE 99999999

START 1

CACHE 1;

ALTER TABLE "public"."control_alarm_info_uid_seq " OWNER TO "postgres";

接下来创建“父表”,

-- Table: control_alarm_info

-- DROP TABLE control_alarm_info;

CREATE TABLE control_alarm_info

(

uid bigserial NOT NULL,

status bigint,

create_time timestamp without time zone,

update_time timestamp without time zone,

creator character varying(32),

store_id integer,

store_name character varying(255),

target_id integer,

person_name character varying(255),

telphone character varying(255),

alarm_time character varying(255),

face_picurl character varying(255),

camera_info_id character varying(255),

camera_name character varying(255),

event_log_id character varying(255),

similarity real,

person_code character varying(64),

alarm_type character varying(255),

bkg_picurl character varying(255),

app_key character varying(64)

)

WITH (

OIDS=FALSE

);

ALTER TABLE control_alarm_info4

OWNER TO postgres;

  • 按时间触发,创建n个子表

  • 创建n个子表,每个子表都是继承于父表

由于每个分区表都是从父表继承的,所以分区表不会增加任何字段,下面我们按需求创建4张分区子表,分别用于存放9月、10月、11月和12月的日志数据:

create table control_alarm_info_201809

(CHECK (alarm_time >= '2018-09-01' AND alarm_time < '2018-10-01'))

INHERITS (control_alarm_info);

create table control_alarm_info_201810

(CHECK (alarm_time >= '2018-10-01' AND alarm_time < '2018-11-01'))

INHERITS (control_alarm_info);

create table control_alarm_info_201811

(CHECK (alarm_time >= '2018-11-01' AND alarm_time < '2018-12-01'))

INHERITS (control_alarm_info);

接下来在这4张分区表的每个分区键上建立索引:

在上面的语句中我们添加了一个约束表示只允许插入本月的数据,接下来在这4张分区表的每个分区键上建立索引:

create index control_alarm_info_201809_alarm_time ON control_alarm_info_201809 (alarm_time);

create index control_alarm_info_201810_alarm_time ON control_alarm_info_201810 (alarm_time);

create index control_alarm_info_201811_alarm_time ON control_alarm_info_201811(alarm_time);

查询时查询条件中包含这些索引时才会提高查询效率,如果能定位到一张子表内,效率更高。

  • 定义一个规则(Rule)或触发器(Trigger),把对主表的数据插入重定向到合适的分区表

如何才能让不同日期的数据自动的插入与其对应的分区子表中呢?有两种解决方案,分别是:规则(Rule)和触发器(Trigger),相比触发器,Rule的开销更大,所以我在这里就不做过多介绍了,下面直接介绍Trigger的方式。

Trigger通常会结合自定义函数(Function)来实现分区插入,Function负责根据条件选择插入,而Trigger则负责Function的自动调用。首先定义Function,功能很简单,即根据日期区间insert数据即可:

Drop trigger control_alarm_info_insert_trigger;

CREATE

OR REPLACE FUNCTION control_alarm_info_insert_trigger () RETURNS TRIGGER AS $$

BEGIN

IF (

NEW .alarm_time >= '2018-09-01'

AND NEW .alarm_time < '2018-10-01'

) THEN

INSERT INTO control_alarm_info_201809

VALUES

(NEW .*) ;

ELSEIF (

NEW .alarm_time >= '2018-10-01'

AND NEW .alarm_time < '2018-11-01'

) THEN

INSERT INTO control_alarm_info_201810

VALUES

(NEW .*) ;

ELSEIF (

NEW .alarm_time >= '2018-11-01'

AND NEW .alarm_time < '2018-12-01'

) THEN

INSERT INTO control_alarm_info_201811

VALUES

(NEW .*) ;

ELSE

RAISE EXCEPTION 'Date out of range!' ;

END

IF ; RETURN NULL ;

END ; $$ LANGUAGE plpgsql;

最后再创建触发器用于执行刚才的Function:

CREATE TRIGGER control_alarm_info_insert_trigger  BEFORE INSERT ON control_alarm_info

FOR EACH ROW

EXECUTE PROCEDURE control_alarm_info_insert_trigger();

未分表时200万数据中查询最后一条告警记录,2.505s

分表后200万数据中查询最后一条告警记录,0.221s,提升了10倍

插入性能

未分表时200万数据中插入10万条数据,需要104s

标签:info,control,Postgres,alarm,varying,character,time,分表
From: https://www.cnblogs.com/bigleft/p/18153556

相关文章

  • 22.Postgresql的checkpoint功能
    PostgreSQL中的checkpoint是数据库管理系统(DBMS)中的一项重要机制,用于确保数据的一致性、可恢复性和性能管理。以下是关于PostgreSQLcheckpoint的详细解释:checkpoint的定义与作用定义:Checkpoint是一个在WAL(Write-AheadLog)序列中的点,此时所有数据文件已更新,反映了到该点为止......
  • postgresql重置序列和自增主键
    1.问题背景数据表中插入了几条测试数据,后又手动删除,导致后面插入数据的时候报主键冲突:ERROR:duplicatekeyvalueviolatesuniqueconstraint"tableName_pkey"DETAIL:Key(id)=(1)alreadyexists.12即使采用INSERTIGNORE的方式或者REPLACEINTO的方式还是报错,所以就想......
  • PostgreSQL源码编译安装指南
    一、版本说明centos7.9postgresql12.2二、配置系统基本环境#1.创建postgres用户groupaddpostgresuseradd-gpostgrespostgresecho"666666"|passwdpostgres--stdin#2.配置用户环境变量su-postgrescat>>~/.bash_profile<<EOFexportPGPORT=1922expor......
  • postgresql数据定时转存mongodb方案
    案例背景很多事件记录在最初一段时间读写比较频繁,存储在postgresql比较合适,后期数据量变大,且仅作为历史记录查询,更适合存储在mongodb中,可能需要定期将postgresql中的数据转存到mongodb。案例分析postgresql数据定时转存mongodb,可以采用jdbc方式将postgresql读入内存,对每条......
  • LightDB兼容扫描 - 事前SQL兼容迁移评估工具24.1支持MySQL --> TDSQL-PostgreSQL兼容
    兼容扫描工具下载地址:事前SQL兼容迁移评估工具使用说明:LightDB-事前SQL兼容迁移评估工具使用手册本次24.1版本新增了对MySQL迁移到TDSQL-pg的兼容性扫描。工具的具体使用方法请阅读使用说明文档,针对本次更新,涉及配置项targetDataBase改为MySQL-to-TDSQL-PostgreSQL。以下是......
  • Ubuntu22.04安装PostgreSQL15
    Ubuntu22.04安装PostgreSQL15启用PostgreSQL包存储库sudosh-c'echo"debhttp://apt.postgresql.org/pub/repos/apt$(lsb_release-cs)-pgdgmain">/etc/apt/sources.list.d/pgdg.list'wget-qO-https://www.postgresql.org/media/keys/ACCC4CF8......
  • PostgreSql: ERROR: value too long for type character varying(1) 定位字段方法
    报错原因设置的数据库字段长度为1,但实际的值超过规定字段,导致报错。解决方案首先,需要定位字段是哪个字段出现的报错,但可惜的是,并没有报出具体是哪个字段在报错,所以只能通过检查Schema,查看哪些字段是长度为1的,然后再进行值的比较,才能锁定位置。ERROR:valuetoolongfortype......
  • 安装postgres
    安装postgresqlyum安装官网参考:https://www.postgresql.org/download/linux/redhat/#InstalltherepositoryRPM:sudoyuminstall-yhttps://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm#InstallPostgreSQL:s......
  • postgres docker安装
    docker-compose文件version:'3.1'services:db:image:postgres:15container_name:odoo16_dbrestart:always#总是重新启动容器environment:-POSTGRES_DB=postgres#设置数据库名称为postgres-POSTGRES_PASSWORD=odoo#设置数......
  • Ubuntu下离线安装PostgreSQL
      首先,我的环境是Ubuntu20.04  如果是在线安装,根据官网的介绍很简单#安装包sudoaptupdatesudoaptinstallwgetgnupg#导入仓库sudosh-c'echo"debhttps://apt.postgresql.org/pub/repos/apt$(lsb_release-cs)-pgdgmain">/etc/apt/......