我对PostgreSQL 中 执行计划的处理范围的理解

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
简介:

开始

我有一个表,大约有一千万条记录,当我运行一个insert 命令向另一个表插入数据时,由于约束和索引的存在,导致插入数据很慢。

但是这也给了我一个机会,来观察 explain plan 是如何处理数据的。 

复制代码
postgres=# create table ptest(id integer, name varchar(20));
CREATE TABLE
postgres=# create table ctest01(CHECK(id<5000000)) inherits (ptest);
CREATE TABLE
postgres=# create table ctest02(CHECK(id>=5000000)) inherits (ptest);
CREATE TABLE
postgres=# 
postgres=# create index on ctest01(id);
CREATE INDEX
postgres=# create index on ctest02(id);
CREATE INDEX
postgres=# 
postgres=# 

postgres=# CREATE OR REPLACE FUNCTION ptest_insert_trigger() RETURNS TRIGGER AS $$ 
postgres$# 
postgres$# BEGIN 
postgres$# 
postgres$#    IF ( NEW.id <5000000 ) THEN 
postgres$#        INSERT INTO ctest01 VALUES (NEW.*);
postgres$#    ELSIF ( NEW.id >= 5000000 ) THEN 
postgres$#        INSERT INTO ctest02 VALUES (NEW.*); 
postgres$#    ELSE 
postgres$#        RAISE EXCEPTION 'Error while inserting data';
postgres$#    END IF; 
postgres$#   
postgres$#   RETURN NULL;
postgres$# END; $$ LANGUAGE plpgsql;
CREATE FUNCTION
postgres=# 
postgres=# CREATE TRIGGER insert_ptest_trigger BEFORE INSERT ON ptest FOR EACH ROW 
postgres-#   EXECUTE PROCEDURE ptest_insert_trigger();
CREATE TRIGGER
postgres=# 
复制代码

我的test02 表,有一千万条数据,下面我来拷贝数据:

insert into ptest select * from test02;

由于数据量大,约束也在起作用,所以运行了很久(事实上两天后崩溃了(我用的是虚拟机))。

在此期间,我开了另外的session, 来执行查询:

复制代码
postgres=# explain select count(*) from ptest;
                                    QUERY PLAN  
-----------------------------------------------------------------------------------
 Aggregate  (cost=55406.40..55406.41 rows=1 width=0)
   ->  Append  (cost=0.00..49601.92 rows=2321793 width=0)
         ->  Seq Scan on ptest  (cost=0.00..0.00 rows=1 width=0)
         ->  Seq Scan on ctest01 ptest  (cost=0.00..24776.52 rows=1159752 width=0)
         ->  Seq Scan on ctest02 ptest  (cost=0.00..24825.40 rows=1162040 width=0)
(5 rows)postgres=# 
复制代码

其实如果执行 select count(*) from ptest, 由于前面的session 的插入动作耗时很久,尚未结束故尚未提交。所以返回的结果是零。

那么为何执行计划分别在两个子表中看到了 各一百多万条的记录呢?

PostgreSQL 的物理存储结构中,没有像oracle 那样的rollback或undo segment,所有的数据映像,都存放在数据块中。如果不进行vacuum操作,旧的已经提交的数据、刚刚刷入磁盘未提交的数据和已经提交的数据就都会在数据块中。

如果我作一个程序,每1分钟修改某表格数据的特定记录一次但是不提交,只要我的事务足够长,那么这将会不断地刷入数据到数据块中。这是PostgreSQL 的一个弱点,也是被人诟病之处。

可以说,在一个并发性很高的系统里,每一次的sql 执行,其成本的一个重要方面,就是磁盘访问物理I/O,而由于PostgreSQL 把数据的前映像(提交的和未提交的)、当前映像(提交的和未提交的),都存放在一起,使得每个sql访问互相影响(因为有未提交的数据掺和),无疑地降低了性能。

在PostgreSQL 社区询问的结果是,如果只是想看近似的结果,不想用太大代价,可以从 pg_class 入手:

SELECT sum(reltuples) FROM pg_class WHERE relname IN ('ptest', 'ctest01', 'ctest02');

结束






本文转自健哥的数据花园博客园博客,原文链接:http://www.cnblogs.com/gaojian/archive/2012/11/12/2765749.html,如需转载请自行联系原作者

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
9月前
|
关系型数据库 PostgreSQL
PostgreSQL执行计划explain
PostgreSQL执行计划explain
82 0
|
9月前
|
关系型数据库 PostgreSQL 索引
PostgreSQL执行计划数据结构
PostgreSQL执行计划数据结构
55 0
|
11月前
|
SQL Cloud Native 关系型数据库
《阿里云认证的解析与实战-数据仓库ACP认证》——云原生数据仓库AnalyticDB PostgreSQL版功能演示(上)——六、查看分析执行计划
《阿里云认证的解析与实战-数据仓库ACP认证》——云原生数据仓库AnalyticDB PostgreSQL版功能演示(上)——六、查看分析执行计划
|
11月前
|
关系型数据库 PostgreSQL 索引
PostgreSQL 性能优化: 执行计划
PostgreSQL为每个收到的查询产生一个查询计划。查询计划的结构是一个计划结点的树。最底层的结点是扫描结点:它们从表中返回未经处理的行。不同的表访问模式有不同的扫描结点类型:顺序扫描、索引扫描、位图索引扫描。也还有不是表的行来源,例如VALUES子句和FROM中返回集合的函数,它们有自己的结点类型。如果查询需要连接、聚集、排序、或者在未经处理的行上的其它操作,那么就会在扫描结点之上有其它额外的结点来执行这些操作。并且,做这些操作通常都有多种方法,因此在这些位置也有可能出现不同的结点类型。
84 0
|
SQL 关系型数据库 HIVE
hive/postgresql日期时间范围查询数据,没有的数据补0
hive/postgresql日期时间范围查询数据,没有的数据补0
|
SQL 移动开发 关系型数据库
PostgreSQL 执行计划,成本公式解说,代价因子校准,自动跟踪SQL执行计划(三)|学习笔记
快速学习PostgreSQL 执行计划,成本公式解说,代价因子校准,自动跟踪SQL执行计划(三)
545 0
PostgreSQL 执行计划,成本公式解说,代价因子校准,自动跟踪SQL执行计划(三)|学习笔记
|
关系型数据库 SQL MySQL
如何在线应对SQL语句执行计划?解读RDS MySQL 8.0之SQL Outline功能
这里边有几个因素和场景,比如:随着表数据量的变化,以及统计信息的自动收集,CBO optimizer 计算得到了一个cost 更低的 plan, 又或者 表结构发生了变化,增加和删减了某些索引,或者在实例升级迁移等过程中,MySQL 自身优化器行为和算法发生了变化等。
1480 0
|
SQL 关系型数据库
PostgreSQL citus, Greenplum 分布式执行计划 DEBUG
标签 PostgreSQL , citus , sharding , Greenplum , explain , debug 背景 开启DEBUG,可以观察citus, Greenplum的SQL分布式执行计划,下发情况,主节点,数据节点交互情况。
1580 0