PostgreSQL 9 正式版发布


PostgreSQL 是一个自由的对象-关系数据库服务器(数据库管理系统),它在灵活的 BSD 风格许可证下发行。其提供了相对其他开放源代码数据库系统(比如 MySQL 和 Firebird),和对专有系统比如 Oracle、Sybase、IBM 的 DB2 和 Microsoft SQL Server的一种选择。9.0版本的新特性包括:
* 支持热备份与联机升级
* 基于数据流复制
* 提供 64位 Windows 编译版本
* 更强的权限管理
* 存储过程匿名块以及命名参数
PostgreSQL 9.1 版新特性列表
1.推出了诸多企业级特性,开始与SQL Server和Oracle等重量级对手展开正面竞争。
2.内置的复制特性全面增强,支持同步复制。
3.引人新的CREATE EXTENSION和 ALTER EXTENSION命令来管理扩展包,安装和卸载扩展包变得轻而易举。
4.引入兼容ANSI标准的外部数据封装器(FDW)机制,用于查询外部数据源。
5.支持可写CTE表达式,此后UPDATE和INSERT语句也可以享受到CTE语法带来的便利。
6.支持建立无日志的表,以加快写操作速度。有的场景下,记录预写日志确无必要。
7.支持针对视图建立触发器。在之前的版本中,如果希望对视图进行修改操作,只能通过建立DO INSTEAD类型的规则来实现,且这种规则只能用SQL语言编写,但支持视图触发器后,就可以用上 PostgreSQL支持的所有语言,这样就可以针对视图实现更复杂更抽象的业务逻辑。
8.引人 KNN GiST索引类型,该类索引能对常用的很多扩展包带来性能提升,比如全文检索、三连词(用于模糊查找以及区分大小写查找操作)以及PostGIS等。
PostgreSQL 9.2 版本主要在性能方面有很大的提升,也包括一些新的 SQL 特性以及复制支持方面,主要内容包括:
允许查询直接从索引中获取数据,避免访问堆数据 (index-only scans)
允许查询计划器为指定参数值生成自定义的计划,甚至是用了 Prepared Statement
提升计划器通过内部索引扫描来使用嵌套循环
允许流复制从节点将数据转到其他从节点 (cascading replication)
允许 pg_basebackup 对待机的服务器进行基准备份
增加新工具 pg_receivexlog 用来收集 WAL 文件的改动
增加 SP-GiST (Space-Partitioned GiST) 索引访问方法
支持 range data types
增加 JSON 数据类型
为视图增加 security_barrier 选项
允许 libpq 连接字符串使用 URI 格式
为 libpq 增加 single-row processing mode 以更好的处理大结果集。
9.2版新特性列表
(2012年9月发布)中引入的主要特性如下:
1.支持索引内查询。如果查询的列都位于索引内,那么PG会省略不必要的表访问动作,仅依据索引自身数据就可以完成全部查询动作。该优化会给键值查询以及类似COUNT(*)这种聚合查询带来巨大的性能提升。
2.内存排序操作性能提升可达20%。
3.在预处理语句中做了一些改进。现在会对预处理语句进行解析、分析和重写,但可以跳过该计划来避免被绑定到特定实参输入上。现在还可以保存依赖实参的某个预处理语句的计划。这样会降低预处理语句比等效的即席查询执行得更差的几率:语句的PREPARE预解析机制有改进。在之前版本中进行PREPARE操作时规划器会对预解析的语句生成执行计划,但由于此时的语句中不携带具体的选项值(预提交的语法形式如PREPARE ry_stmtAS select a fron tab where b=$1 and c>$2),因此规划器会基于表的统计信息来进行推测,并生成一个通用的、比较保守的执行计划,这往往会导致得到的执行计划并非最优,从而出现语句经过预解析后再执行反而比直接执行更慢的情况。为解决此问题,当前版本中的PREPARE操作有所变化,仍然会执行语句解析、语句分析、语句改写这几个过程,但会跳过生成执行计划这一步骤,留到语句EXECUTE阶段根据真正的选项再生成执行计划,这样就保证了执行计划是最优的。但这带来的另一个问题就是EXECUTE效率降低,因为每次都要生成执行计划。为此系统做了另一个优化:如果EXECUTE阶段生成的执行计划与原来在PREPARE阶段生成的通用执行计划效率类似,那么系统还是会将通用执行计划存储下来并复用。通过以上策略,避免了有时执行预提交的语句反而更慢的情况。
4.支持级联流式复制,即支持从一个 slave节点到另一个slave节点的流式复制。
5.支持基于空间分区树算法的SP-GiST索引,这种索引是GiST索引的强化版本,对于很多依赖GiST索引的扩展包来说,使用这种索引可以得到巨大的性能提升。
6.新增了对 ALTER TABLE IF EXISTS语法的支持,修改表结构之前可以不用再检查此表是否存在。
7.ALTER TABLE 和 ALTER TYPE 这两个命令新增了大量功能选项,本来要实现这些功能的话需要删除表并重建。更多细节请参见 depesz博客网站的“More Alter Table Alter Types"这篇博文。
8.增加了更多的pg _dunp和 pg_restore选项。细节请参见“9.2版中p9_durp工具的增强”。
9.新增了对PLV8语法扩展包的支持,以后可以使用目前非常流行的 JavaScript 语言来编写函数。
10.JSON正式成为系统内置数据类型,同时转正的还有row_to_json和array_to_json函数。使用Ajax的Web开发人员应该会很欢迎该特性。
11.新增了对区间数据类型的支持,不再需要通过编写函数来实现类似功能。区间类型虽然是首次引入,但系统为其提供了丰富的运算符和配套函数。Exclusion类型的约束可以很好地保证该类型数据的合法性。
12.支持在SOL函数中通过实参名称引用实参,之前版本仅支持通过实参编号引用实参。有多个实参时通过实参名称引用会更方便。
性能与扩展性改进
在9.2版本中,线性扩展性将支持64核,并增加了仅索引扫描(index-only scans)减少了CPU消耗,这意味着它在应对大多数工作负载时将对扩展性和开发者灵活性实现极大的提升。据了解,目前美国联邦航空管理局、Heroku.com都使用了PostgreSQL作为后端数据库,另外惠普公司也用它支撑远程支持软件并捆绑到HP-UX/Itanium解决方案中。增强的垂直扩展能力使得PostgreSQL能够更高效地利用大型服务器的硬件资源。锁管理、写入效率、仅索引访问以及其他底层操作使得数据库引擎可以处理更大型的工作负载。体现在数字上,这意味着:
每秒钟35万次读查询(4倍性能提升)
针对数据仓库查询的仅索引扫描性能提升2-20倍
每秒写入14000条数据(5倍性能提升)
此外级联复制功能还可以让9.2跑在更大型的服务器集群当中。
更灵活的开发者支持
PostgreSQL的灵活性表现在许多组织都能够使用它来支撑关键业务应用,从NASA到芝加哥商品交易所再到社交新贵Instagram。最新的PostgreSQL 9.2提供了对Range Types和JSON的支持,为开发者提供了更多的思路和使用方式。原生JSON数据类型的支持受到了普遍的关注,9.2中查询结果可以返回JSON类型。外加新的PL/V8 Javascript、PL/Coffee数据库编程扩展以及可选的HStore KV存储,用户现在甚至可以将PostgreSQL作为一个NoSQL文档型数据库,同时还能够保持原有的稳定性、灵活性和性能。
在PostgreSQL 9.2 发行的前几天的2010年7月下旬,Robert Haas提交了一个名为JSON for 9.2的补丁,欲将JSON列为PostgreSQL的核心类型。该补丁功能是对文本进行解析,确保它是有效的JSON数据,并加以存储。这个功能原本打算在9.2版本中放弃的,不过考虑了下发现Robert的补丁太小了点,因此决定继续并又添加了一些功能,包括:query_to_json()、array_to_json()以及record_to_json(),完成了从ProstgreSQL生成JSON数据。以下是来自测试中的一些简单示例:
SELECT query_to_json('select x as b, x * 2 as c from generate_series(1,3) x',false);
query_to_json
---------------------------------------------
[{"b":1,"c":2},{"b":2,"c":4},{"b":3,"c":6}]
(1 row)
SELECT array_to_json('{{1,5},{99,100}}'::int[]);
array_to_json
------------------
[[1,5],[99,100]]
(1 row)
-- row_to_json
SELECT row_to_json(row(1,'foo'));
row_to_json
---------------------
{"f1":1,"f2":"foo"}
(1 row)
更简单一点的:
SELECT row_to_json(q)
FROM (SELECT $$a$$ || x AS b,
y AS c,
ARRAY[ROW(x.*,ARRAY[1,2,3]),
ROW(y.*,ARRAY[4,5,6])] AS z
FROM generate_series(1,2) x,
generate_series(4,5) y) q;
row_to_json
--------------------------------------------------------------------
{"b":"a1","c":4,"z":[{"f1":1,"f2":[1,2,3]},{"f1":4,"f2":[4,5,6]}]}
{"b":"a1","c":5,"z":[{"f1":1,"f2":[1,2,3]},{"f1":5,"f2":[4,5,6]}]}
{"b":"a2","c":4,"z":[{"f1":2,"f2":[1,2,3]},{"f1":4,"f2":[4,5,6]}]}
{"b":"a2","c":5,"z":[{"f1":2,"f2":[1,2,3]},{"f1":5,"f2":[4,5,6]}]}
(4 rows)
更详细介绍和移植指南请看官方发行说明。
2013年9月上旬官宣 PostgreSQL 9.3 正式版发布了,该版本包含可写的外部数据封装、数据页 checksums、快速的故障转移以及 streaming-only remastering 等等。外部数据封装可写使得系统间支持双路数据交换。今天非常复杂的IT环境涉及到多个数据库和半结构化的数据源,而PG可帮你将它们集成在一起。该项目同时发布了postgres_fdw ,这是一个高性能的支持读写的联合驱动程序。此外,该版本提升了可靠性和可用性,实现了快速的故障转移;数据页的checksum。此外在复杂的复制环境中,可在故障发生时迅速转移主数据节点。在针对开发者方面改进包括:
额外的 JSON 构建和解析方法
自动可更新的视图与LATERAL JOINs
并行 pg_dump 用于加速大数据库的备份
9.3版新特性列表
(发布于2013年)中引入的主要特性如下:
1.增加了对 ANSI SOL 的标准LATERAL子句的支持。LATERAL语法允许将FROM子句与关联一起使用以引用关联的另一方上的变量。在一个关联查询语句中,如果参与关联的一方是一个临时结果集,比如一个子查询或者一个能够返回结果集的函数,那么在该子查询或者函数中可以引用关联关系另一方结果集中的列。如果没有LATERAL语法,这种横向关联是不可能的,只有WHERE关联条件部分才能进行被关联方之间列的交叉引用。如果需要使用unnest、generate_series或者以正则表达式作为查询条件的查询语句来构造关联一方的结果集,那么LATERAL语法几乎是不可或缺的,因为这种情况下势必要参考关联关系另一方的数据才能生成自己一方的数据。
2.支持并行pg_durmp。从8.4版开始支持并行恢复,在该版本中实现了对并行备份的支持,这可以大大加快大型数据库的备份速度。
3.支持物化视图可以将经常使用的视图中的数据进行持久化,从而避免反复执行相同的查询。
4.支持自动可更新视图。对视图执行更新操作不再需要创建触发器或者规则,现在可以直接针对视图执行UPDATE操作,该操作在系统内部会自动映射到此视图的基表上。
5.支持定义基于递归CTE表达式的视图。
6.支持更多针对JSON类型的构造函数和解析函数;支持在基于正则表达式条件的查询中使用索引。
7.引入了支持64位大对象操作的API,该API可操作TB级大小的对象。之前最多支持到2GB。
8.postgres_fdw驱动程序支持对其他PostgreSQL数据库(即使在使用较低版本PostgreSQL的远程服务器上)进行读写操作。伴随此更改的是对实施可写功能的FDW API的升级。
9.复制功能做了大量改进,其中最主要的两点是:实现了复制功能的架构无关性,即复制的架构不依赖于特定的操作系统或者硬件;另外支持了基于流式复制的重新选主过程。
10.支持使用C语言创建后台工作线程,可用于执行一些定时任务。
11.支持对DDL操作定义触发器。
12.支持新的psql命令:watch。
13.支持新的COPY DATA命令,可用于 PostgreSQL 与外部程序之间导入或者导出数据。
更多详细介绍请看发行说明。
PostgreSQL 全球开发组于2015年1月是旬宣布 PostgreSQL 9.4 正式版发布了,该版本添加很多新特性,增强了 PG 的灵活性、伸缩性和提升了整体性能。同时改进对 JSON 的支持,增强了复制和索引的性能。9.4 引入对 JSONB 的支持;新版本的逻辑解码提供了新的 API 用于新的复制工具,例如双向复制支持多个 master 节点的集群方式,同时提供复制间隙和时延复制,改进了复制的管理。此外 PG 9.4 在性能方面也做了很多提升,包括如下几个方面:
改进 GIN 索引,体积缩小 50%,速度提升 3 倍
并发更新物化视图速度更快,更及时的报告
使用 pg_prewarm 重启时快速重载数据库缓冲
更快的并发写 PG 事务日志
支持 Linux 大内存页面
9.4版新特性列表
物化视图特性的改进,在9.3版中刷新物化视图期间会对其加锁并禁止访问。但一般来说刷新物化视图会需要一定的时间,因此在生产环境中该刷新动作会导致物化视图可用性显著降低;9.4版中取消了刷新时的加锁动作,因此即使是正在被刷新的物化视图也可被访问。但请注意:利用此特性的前提是物化视图必须要拥有一个唯一索引。
新增了对SQL:2008标准中规定的percentile_disc(不连续百分比)和percentile_cont(连续百分比)这两个分析函数的支持,须配合WITHIN GROUP(ORDER BY...)子句使用。详细例子可参见depesz博客网站的一篇关于ORDERED SET WITHIN GROUP聚合运算的介绍文章。这些函数提供了系统原生的快速取中间值功能。例如希望从一批考试成绩中取中间点到3/4处部分的值,可执行以下查询:
SELECT subject,percentile_cont(ARRAY[0.5,0.75])
WITHIN GROUP (ORDER BY score) As med_75_score FROM test_scores GROUP BY subject;
在PG中要实现percentile_cont和percentile_disc,可以取一个数组或0到1之间的单个值(此值代表所希望查询的百分比范围),并且此实现会相应地返回一个值数组或单个值。语句中的ORDER BY score表示希望根据score字段的值来进行百分比计算。
创建视图时支持WITH CHECK OPTION子句,其作用是确保在视图上执行更新或者插入操 作时,修改后或者新插入的记录仍然是在本视图可见范围内。
新增对jsonb数据类型的支持,该数据类型是JSON (JavaScript Object Notation)类型的二进制存储版本,并且支持索引。通过jsonb类型可以对JSON格式的文档数据建立索引,并可加快对其内部元素的访问速度。可参考这两篇博客文章:“引入新的 jsonb数据类型:JSON类型的结构化存储格式”以及“jsonb:通配符查询”。
GIN索引的查询速度提升,同时占用空间减少。GIN索引的使用范围日益广泛,并且非常适用于全文搜索、三连词处理、hstore键值数据库以及jsonb类型支持等场景。在很多情况下你甚至可以把它当作B-树索引的一个替代品,而且一般来说GIN索引占用的空间会更少。详情请参见“使用GIN索引来代替位图索引”这篇文章的介绍。.
支持更多JSON函数。请参见Depesz博客站的文章“9.4版中的新JSON函数介绍”。
支持使用以下语法轻松地将所有资产从一个表空间移动到另一个表空间中:ALTER
TABLESPACE old_space MOVE ALL TO new_space;。
支持对返回的结果集中的记录加上数字编号。当从数组、hstore、复合类型等格式数据源中取出非格式化数据时,由于缺少可用于唯一标识记录的主键,因此一般需要为每条记录加一个数字型的行号。现在可以将系统列ordinality(该列是在ANSI SQL标准中定义的)添加到输出。以下是一个使用hstore对象以及返回一个键值对的each 函数的例子:
SELECT ordinality, key, value
FROM each('breed=>pug,cuteness=>high'::hstore) WITH ordinality;
支持通过执行SOL命令来更改系统配置设置。ALTER system SET ... 语法可实现对全局系统设置的动态修改,这一功能在之前版本中只能通过修改 postgresql.conf文件才能实现。
支持对外部表建触发器。通过该功能,即便外部数据源与你相隔万里之遥,只要对方一修改数据,你立即就可以得到通知。不过目前尚不确定该功能的实际使用效果到底如何,因为在数据源极其遥远的情况下由于存在网络延迟,其效果就很难说了。
新增unnest函数,该函数以可预见的方式将不同大小的数组分配到各个列中。
新增ROWS FROM语法,该语法可以将多个函数返回的结果集逐行拼接起来,最后作为一个完整的结果集返回,因此即使这些结果集之间的元素个数不一致也没关系,如下例所示:
SELECT * FROM ROWS FROM (
jsonb_each('{"a" : "foo1", "b" : "bar"}'::jsonb),jsonb_each('{"c": "foo2"}'::jsonb)) x (a1,a1_val,a2_val);
支持使用C对动态后台工作线程进行编码以按需完成工作。contrib/worker_spi目录下的9.4版源码中实现了一个小型的示例可供参考。
更多信息请参考此处。
--------------------------------
Postgres 9.4 Feature Highlight - WITH ORDINALITY
9.4 is going to be shipped with a feature of the SQL standard called WITH ORDINALITY. Introduced by this commit:
Author: Greg Stark <stark@mit.edu>
Date: Mon Jul 29 16:38:01 2013 +0100
Add SQL Standard WITH ORDINALITY support for UNNEST (and any other SRF)
Author: Andrew Gierth, David Fetter
Reviewers: Dean Rasheed, Jeevan Chalke, Stephen Frost
SELECT * FROM generate_series(4,1,-1) WITH ORDINALITY;
The default column name called “ordinality”, but it is possible to associate an alias to it, like that for example:
SELECT t.* FROM json_object_keys('{"a1":"1","a2":"2","a3":"3"}') WITH ORDINALITY AS t(keys,n);
This feature is actually pretty useful when used with arrays when decomposing them with unnest().
SELECT * from unnest(array[array[14,41,7],array[54,9,49]]::int[]) WITH ORDINALITY AS t(elts,num);
And it is actually far more interesting with the new feature called ROWS FROM (or multi-argument unnest), because you can associate a counter usable for some ORDER BY operations easily with that.
SELECT * FROM unnest('{1,2,3}'::int[], '{4,5,6,7}'::int[]) WITH ORDINALITY AS t(a1, a2, num) ORDER BY t.num DESC;
PGv9.4开始支持SQL标准中的WITH ORDINALITY写法,用来返回记录的每一行行号。当 from语句后面的函数加上 WITH ORDINALITY 属性后,那么返回的结果集将增加一个整数列,这个整数列从 1 开始,并且按 1 递增。
注意:WITH ORDINALITY必须使用在from子句中,且要紧跟在函数后面使用!目前不支持返回record类型的函数。
# select * from unnest(array['f','r','e','e','o','a']) with ordinality;
unnest | ordinality
----+----
f | 1
r | 2
e | 3
e | 4
o | 5
a | 6
# select * from generate_series(2,5,2) with ordinality;
generate_series | ordinality
---+---
2 | 1
4 | 2
# select * from generate_series(2,5,2) with ordinality as f(id,ord);
# select * from (values (1),(2),(3)) v(r) LEFT JOIN generate_series(11,13) with ordinality as f(i,o) ON (r+i)<100;
r | i | o
---+---+---
1 | 11 | 1
1 | 12 | 2
1 | 13 | 3
2 | 11 | 1
2 | 12 | 2
2 | 13 | 3
3 | 11 | 1
3 | 12 | 2
3 | 13 | 3
ROWS FROM
9.4 is the WITH ORDINALITY ANSI-SQL construct. What this construct does is to tack an additional column called ordinality as an additional column when you use a set returning function in the FROM part of an SQL Statement.
Basic WITH ORDINALITY
SELECT * FROM unnest('{my,dog, eats, dog food}'::text[]) WITH ordinality;
unnest | ordinality
----------+------------
my | 1
dog | 2
eats | 3
dog food | 4
If you aren't happy with the default column names, you can change them by revising your query like this:
SELECT f.* FROM unnest('{my,dog, eats, dog food}'::text[]) WITH ordinality As f(phrase, sort_order);
phrase | sort_order
----------+------------
my | 1
dog | 2
eats | 3
dog food | 4
LATERAL WITH ORDINALITY
The greatest value of WITH ORDINALITY comes when you apply it to rows of data. How do you do that when you need to use WITH ORDINALITY. This is where one of our favorite constructs, the LATERAL construct comes to the rescue.
First let's construct our table with a text array column for demonstration. Note that the fish has no tags.
CREATE TABLE pets(pet varchar(100) PRIMARY KEY, tags text[]);
INSERT INTO pets(pet, tags)
VALUES ('dog', '{big, furry, friendly, eats steak}'::text[]),
('cat', '{small, snob, eats greenbeans, plays with mouse}'::text[]),
('mouse', '{very small, fits in pocket, eat peanuts, watches cat}'::text[]),
('fish', NULL);
If you do a cross join, you'll leave out fish because he's got no tags:
SELECT pet,sort_order,tag FROM pets,unnest(tags) WITH ORDINALITY As f(tag,sort_order);
In order to include pets that have no tags, you need to do a LEFT JOIN like so:
SELECT pet,sort_order,tag FROM pets LEFT JOIN
LATERAL unnest(tags) WITH ORDINALITY As f(tag,sort_order) ON true;
继续来看实例
CREATE TABLE uns1(id int2 PRIMARY KEY, elements varchar(99));
insert into uns1(id,elements) values (1,'ab,cd,efg,hi'),(2,'jk,lm,no,pq'),(3,'rstuv,wxyz');
unnest() with element number
When I have a column with separated values, I can use the unnest() function:
id | elements
---+------------
1 |ab,cd,efg,hi
2 |jk,lm,no,pq
3 |rstuv,wxyz
select id, unnest(string_to_array(elements, ',')) AS elem from myTable;
id | elem
---+-----
1 | ab
1 | cd
1 | efg
1 | hi
2 | jk
...
How can I include element numbers? I.e.:
id | elem | nr
---+------+---
1 | ab | 1
1 | cd | 2
1 | efg | 3
1 | hi | 4
2 | jk | 1
...
I want the original position of each element in the source string. I've tried with window functions (row_number(), rank() etc.) but I always get 1. Maybe because they are in the same row of the source table?
Postgres 9.4 or later
Use WITH ORDINALITY for set-returning functions:
When a function in the FROM clause is suffixed by WITH ORDINALITY, a bigint column is appended to the output which starts from 1 and increments by 1 for each row of the function's output. This is most useful in the case of set returning functions such as unnest().
In combination with the LATERAL feature in pg 9.3+, and according to this thread on pgsql-hackers, the above query can now be written as:
SELECT t.id, a.elem, a.nr FROM tbl AS t
LEFT JOIN LATERAL unnest(string_to_array(t.elements, ',')) WITH ORDINALITY AS a(elem, nr) ON true;
LEFT JOIN ... ON true preserves all rows in the left table, even if the table expression to the right returns no rows. If that's of no concern you can use this otherwise equivalent, less verbose form with an implicit CROSS JOIN LATERAL:
SELECT t.id, a.elem, a.nr
FROM tbl t, unnest(string_to_array(t.elements, ',')) WITH ORDINALITY a(elem, nr);
--倒排
SELECT t.id, a.elem, a.nr
FROM uns1 t, unnest(string_to_array(t.elements, ',')) WITH ORDINALITY a(elem,nr) order by t.id,a.nr desc;
Or simpler if based off an actual array (arr being an array column):
insert into table2 select id,string_to_array(elements,',') from table1;
SELECT t.id, a.elem, a.nr FROM tbl t, unnest(t.arr) WITH ORDINALITY a(elem, nr);
Or even, with minimal syntax:
SELECT id, a, ordinality FROM tbl, unnest(arr) WITH ORDINALITY a;
a is automatically table and column alias. The default name of the added ordinality column is ordinality. But it's better (safer, cleaner) to add explicit column aliases and table-qualify columns.
Postgres 8.4 - 9.3
With row_number() OVER (PARTITION BY id ORDER BY elem) you get numbers according to the sort order, not the ordinal number of the original ordinal position in the string.
Can simply omit ORDER BY:
SELECT *, row_number() OVER (PARTITION by id) AS nr
FROM (SELECT id, regexp_split_to_table(elements, ',') AS elem FROM tbl) t;
select v.*, row_number() over (partition by id order by elem) rn from
(select id,unnest(string_to_array(elements, ',')) AS elem from uns1) v
While this normally works and I have never seen it fail in simple queries, PostgreSQL asserts nothing concerning the order of rows without ORDER BY. It happens to work due to an implementation detail.
To guarantee ordinal numbers of elements in the blank-separated string:
SELECT id, arr[nr] AS elem, nr
FROM (SELECT *, generate_subscripts(arr, 1) AS nr FROM (SELECT id, string_to_array(elements, ' ') AS arr FROM tbl) t
) sub;
Or simpler if based off an actual array:
SELECT id, arr[nr] AS elem, nr FROM (SELECT *, generate_subscripts(arr, 1) AS nr FROM tbl) t;
Postgres 8.1 - 8.4
Skip...
PostgreSQL 9.5于2016年1月7日正式发布,此版本主要带来了以下几个方面的特性: UPSERT, Row Level Security, and Big Data。下面是新特性的用法示例,更多的特性可以参考PDF文档。
该版本主要在性能方面有很大的提升,也包括一些新的 SQL 特性以及复制支持方面,主要内容包括:
允许查询直接从索引中获取数据,避免访问堆数据 (index-only scans)
允许查询计划器为指定参数值生成自定义的计划,甚至是用了 Prepared Statement
提升计划器通过内部索引扫描来使用嵌套循环
允许流复制从节点将数据转到其他从节点 (cascading replication)
允许 pg_basebackup 对待机的服务器进行基准备份
增加新工具 pg_receivexlog 用来收集 WAL 文件的改动
增加 SP-GiST (Space-Partitioned GiST) 索引访问方法
支持 range data types
增加 JSON 数据类型
为视图增加 security_barrier 选项
允许 libpq 连接字符串使用 URI 格式
为 libpq 增加 single-row processing mode 以更好的处理大结果集。
这一系列版本都是为了修复同一个高危的安全漏洞(CVE-2013-1899),强烈建议所有用户立即升级!此外这次更新还包括其他安全问题以及 bug 的修复,更多详情请看发行说明。
1)、UPSERT
UPSERT是INSERT, ON CONFLICT UPDATE的简写,简而言之就是:插入数据,正常时写入,主键冲突时更新。下面给个简单的例子:
--创建测试表,并插入一条数据。
CREATE TABLE customer (cust_id INTEGER PRIMARY KEY, name TEXT);
INSERT INTO customer VALUES (100, ’Big customer’);
--常规INSERT语句,主键冲突,报错。
INSERT INTO customer VALUES (100, ’Non-paying customer’);
ERROR: duplicate key value violates unique constraint
"customer_pkey"
DETAIL: Key (cust_id)=(100) already exists.
--新特性,主键冲突时,自动更新数据。
INSERT INTO customer VALUES (100, ’Non-paying customer’)
ON CONFLICT (cust_id) DO UPDATE SET name = EXCLUDED.name;
SELECT * FROM customer;
cust_id | name
---------+---------------------
100 | Non-paying customer
2)、Row Level Security
行级安全控制:
--创建测试表,并开启行级别安全策略
CREATE TABLE orders (id INTEGER, product TEXT,
entered_by TEXT);
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
CREATE POLICY orders_control ON orders FOR ALL TO PUBLIC
USING (entered_by = CURRENT_USER);
GRANT ALL ON TABLE orders TO PUBLIC;
--创建两个用户
CREATE USER emp1;
CREATE USER emp2;
--分别插入一条数据
SET SESSION AUTHORIZATION emp1;
INSERT INTO orders VALUES (101, ’fuse’, CURRENT_USER);
SET SESSION AUTHORIZATION emp2;
INSERT INTO orders VALUES (102, ’bolt’, CURRENT_USER);
--使用超级用户,可以看到所有纪录。
SET SESSION AUTHORIZATION postgres;
SELECT * FROM orders;
id | product | entered_by
-----+---------+------------
101 | fuse | emp1
102 | bolt | emp2
--普通账号只能看到自己的纪录。
SET SESSION AUTHORIZATION emp1;
SELECT * FROM orders;
id | product | entered_by
-----+---------+------------
101 | fuse | emp1
SET SESSION AUTHORIZATION emp2;
SELECT * FROM orders;
id | product | entered_by
-----+---------+------------
102 | bolt | emp2
3)、Big Data
3.1)、BRIN Indexing
一种占用空间特别小的索引,适合超大数据量且自然排序(如:id递增)的表。
CREATE TABLE brin_example AS
SELECT generate_series(1,100000000) AS id;
CREATE INDEX btree_index ON brin_example(id);
CREATE INDEX brin_index ON brin_example USING brin(id);
SELECT relname, pg_size_pretty(pg_relation_size(oid))
FROM pg_class
WHERE relname LIKE ’brin_%’ OR relname = ’btree_index’
ORDER BY relname;
relname | pg_size_pretty
--------------+----------------
brin_example | 3457 MB
btree_index | 2142 MB
brin_index | 104 kB
--以上三行是关键,看大小!!!
3.2)、Faster Sorts
使用了一种叫做“abbreviated keys”的算法,使得对varchar()、text和NUMERIC()几种类型排序更快,查询提速2~12倍,索引创建提速20倍。
3.3)、CUBE, ROLLUP and GROUPING SETS
聚集函数类sql更好写了,OLAP更方便。示例代码例子太长,就不贴了。
3.4)、Foreign Data Wrappers (FDWs)
外部数据包装,示例代码:
--以前得这个写
CREATE FOREIGN TABLE remote.customers (
id int NOT NULL,
name text,
company text,
registered_date date,
expiry_date date,
active boolean,
status text,
account_level text) SERVER dest_server OPTIONS (schema_name 'public');
CREATE FOREIGN TABLE remote.purchases (
id int NOT NULL,
purchase_time timestamptz,
payment_time timestamptz,
itemid int,
volume int,
invoice_sent boolean) SERVER dest_server OPTIONS (schema_name 'public');
--9.5可以这么写
IMPORT FOREIGN SCHEMA public FROM SERVER dest_server INTO remote;
--其它写法
IMPORT FOREIGN SCHEMA public
EXCEPT (reports, audit)
FROM SERVER dest_server INTO remote;
IMPORT FOREIGN SCHEMA public
LIMIT TO (customers, purchases)
FROM SERVER dest_server INTO remote;
3.5)、TABLESAMPLE
方便对数据进行抽样。
--抽样10%数据
select * from ts_test tablesample system(10);
PostgreSQL越来越强大了,种种迹象来看(BRUCE MOMJIAN说的),PostgreSQL正在朝着多方向发展:
1)Big data大数据:BRIN的支持,Foreign Data Wrappers支持
2)Data analytics 数据分析:grouping sets, cube, rollup的支持
3)Large servers :Faster Sorts,Hashing性能改善,多核大内存支持更好,比如:IBM POWER-8, having 24 cores, 192 hardware threads, and 492GB RAM环境下,TPS达到40万
4)NoSQL:JSONB相关支持,单机性能是MongoDB的好几倍。
参考来源:
PostgreSQL 9.5 有哪些新特性
Gulcin Yildirim: Tablesample In PostgreSQL 9.5
PostgreSQL9.5 给开发人员带来了什么?
PostgreSQL全球开发者在2016年9月29日宣布其最新版本9.6正式发布。此版本将允许用户纵向扩展(scale-up)和横向扩展(scale-out)来提高数据库的查询性能。新功能包括并行查询、同步复制改进、短语搜索、性能和易用性方面的改进,并提供了其它许多方面的功能。
纵向扩展的并行查询
9.6版本现支持一些并行查询操作,因而能够利用服务器上的几个或所有的CPU内核来进行运算,这样返回查询结果更快。此版本的并行功能包括并行顺序表扫描、聚合和联接。根据详细信息和可用内核,并行性可以加快大数据查询,最快时可高达32倍。Synthetic Genomics的首席数据库架构师Mike Sofen表示, “我们将我们整个基因组数据平台–250亿行旧的MySQL数据迁移到一个Postgres数据库, 利用了 JSONB 数据类型的行压缩功能,以及优秀的GIN,BRIN和B-Tree索引模式。期待在9.6版本中,利用并行查询功能,在我们查询大表数据时,拥有更强劲的伸缩性,更优的查询性能”
横向扩展的同步复制与postgres_fdw
PostgreSQL的同步复制功能添加了两个选项,使它能够用于数据库集群一致读取维护。首先,它现在允许配置一组的同步的复制数据库。其次,“remote_apply”模式创建多个跨数据节点的一致的读视图。这些功能使用内置的复制来维护一组的“相同的”节点实现,可以用于数据库的读负载均衡。postgres_fdw(PostgreSQL-to-PostgreSQL数据外部表驱动程序)提供了新的功能,支持在远程服务器上执行操作。通过“下推”(Push Down)排序(sort),Join联接,批量数据更新(update)任务, 用户可以调度多个PostgreSQL服务器来完成数据查询。这些功能很快会添加到其他fdw模块中。Equnix商务解决方案主管Julyanto Sutandang表示,“fdw支持远程联接,更新和删除的功能,是当下其他数据库和 PostgreSQL共享数据的完整解决方案,比如可以实现所录入的数据保存到两个或多个不同类型的数据库的功能”
更好的文本短语搜索
PostgreSQL的全文搜索功能,现在支持短语搜索。这允许用户搜索精确的短语,或是搜索有一定相似性的短语,使用快速的GIN索引中的单词,结合可精细调整的文本搜索选项的新功能,PostgreSQL是“混合搜索”的超优选择,集成了关系表,JSON和全文的搜索支持。
更畅、更快和更易使用
感谢大批PostgreSQL用户使用他们的包含大量数据生产数据库来进行PostgreSQL的反馈和测试,这个版本包括了大量有关性能提升和可用性等方面的内容。复制、聚合、索引、排序和存储过程变得更加高效,在新的Linux内核上,PostgreSQL现在可以可以更好的利用资源,降低了大型表查询和复杂查询的系统负载,尤其是VACUUM的改进。
9.6版本累计近一年来的很多新特性,主要包括︰
新的系统视图和函数:pg_stat_wal_receiver,pg_visbility,pg_config,pg_blocking_pids,pg_notification_queue_usage
支持命令执行进度状态报告
支持级联操作(需安装扩展模块实现)
支持pg_basebackup的并发
逻辑复制插槽
等待事件支持
在psql中编辑视图和crosstabs
用户定义旧快照过期
只扫描局部索引
此外该版本改进并优化了热备流复制的API,这样开发人员可以用自定义的备份工具测试PostgreSQL新版本。更多详细信息请参阅完整发布说明。
并行方式全表扫描功能已提交 PostgreSQL 9.6 版主干代码
2016年1月中旬消息,建议过将并行全表扫描功能加入至PostgreSQL 9.5中,但未实现。现在很高兴地向各位通报已经将第一版本的并行扫描功能提交至PostgreSQL的开发主分支中,确认它将会包含在将要发布的9.6版本中。为PostgreSQL增加并行查询功能,目前这只是第一步,它也是长久以来的一个梦想,已为此工作了好几年了,最早真正开发时是在9.4版本的开发期间,那时主要是开发了一些后台动态进程和动态共享内存;接着在9.5版本期间,又增加了很多有关并行机制的底层基本加松的开发,以及其他包含在提交的补丁的内容。下面想说提交的 主要内容明细和下一步还准备要开发的工作和大家沟通一下。
在开始之前,想首先将这些荣誉给一些应该得的人。首先,Amit Kapila为这个项目中贡献了巨大的帮助。主要是由Amit和我写了这个功能的大部分代码,这些代码经过涵盖在最近几年多次提交的补丁中。我们俩也写了大量的没有包含在补丁 中的代码。第二,我想感谢Noah Misch,在项目早期阶段,在被一些问题给绕得晕头转向时,他给了我很大的帮助;第三,想向整个PostgreSQL社区的成员,尤其是所有帮助我进行代码审核、功能测试、提出改进意见以及在很多其他方面提供帮助而最终使用这个功能得以实现的人们。
最为重要的是,我要感谢EnterpriseDB公司,没有该公司管理上的支持,尤其是来自Tom Kincaid和Marc Linster的支持,也就不可能让我和Amit有大量的时间开发并最终完成这个项目。同样地,没有我在EnterpriseDB公司的团队的支持,我们的项目也不可能现在完成,当我忙于项目开发时,我的同事们耐心地帮助我处理了其他的问题。谢谢所有的人。
好了,现在来看一下测试效果:
rhaas=# \timing
Timing is on.
rhaas=# select * from pgbench_accounts where filler like '%a%';
aid | bid | abalance | filler
-----+-----+----------+--------
(0 rows)
Time: 743.061 ms
rhaas=# set max_parallel_degree = 4;
SET
Time: 0.270 ms
rhaas=# select * from pgbench_accounts where filler like '%a%';
aid | bid | abalance | filler
-----+-----+----------+--------
(0 rows)
Time: 213.412 ms
这里是查询计划的内容:
rhaas=# explain (costs off) select * from pgbench_accounts where filler like '%a%';
QUERY PLAN
---------------------------------------------
Gather
Number of Workers: 4
-> Parallel Seq Scan on pgbench_accounts
Filter: (filler ~~ '%a%'::text)
(4 rows)
目前因该功能还在进一步的开发中,还有一些未处理的问题和使用限制,如现在该功能暂不能在分区表上使用;
仅可对表的全表扫描类查询较有效,有索引的列就用不上了,当然对数据的过滤的操作,多进程并行处理总是要快一些;还有就是并行处理的进程数如何根据系统配置进行最有效设置,以及其他一些小问题还未完全完成。最后请大家多多进行测试,并给我们反馈Bug,谢谢!
以上博文翻译自PostgreSQL主要代码贡献人员之一Robert Haas的博客(详情可浏览此处),同时他也是并行方式全表扫描功能的主要开发人员(原文地址)。
* 支持热备份与联机升级
* 基于数据流复制
* 提供 64位 Windows 编译版本
* 更强的权限管理
* 存储过程匿名块以及命名参数
PostgreSQL 9.1 版新特性列表
1.推出了诸多企业级特性,开始与SQL Server和Oracle等重量级对手展开正面竞争。
2.内置的复制特性全面增强,支持同步复制。
3.引人新的CREATE EXTENSION和 ALTER EXTENSION命令来管理扩展包,安装和卸载扩展包变得轻而易举。
4.引入兼容ANSI标准的外部数据封装器(FDW)机制,用于查询外部数据源。
5.支持可写CTE表达式,此后UPDATE和INSERT语句也可以享受到CTE语法带来的便利。
6.支持建立无日志的表,以加快写操作速度。有的场景下,记录预写日志确无必要。
7.支持针对视图建立触发器。在之前的版本中,如果希望对视图进行修改操作,只能通过建立DO INSTEAD类型的规则来实现,且这种规则只能用SQL语言编写,但支持视图触发器后,就可以用上 PostgreSQL支持的所有语言,这样就可以针对视图实现更复杂更抽象的业务逻辑。
8.引人 KNN GiST索引类型,该类索引能对常用的很多扩展包带来性能提升,比如全文检索、三连词(用于模糊查找以及区分大小写查找操作)以及PostGIS等。
PostgreSQL 9.2 版本主要在性能方面有很大的提升,也包括一些新的 SQL 特性以及复制支持方面,主要内容包括:
允许查询直接从索引中获取数据,避免访问堆数据 (index-only scans)
允许查询计划器为指定参数值生成自定义的计划,甚至是用了 Prepared Statement
提升计划器通过内部索引扫描来使用嵌套循环
允许流复制从节点将数据转到其他从节点 (cascading replication)
允许 pg_basebackup 对待机的服务器进行基准备份
增加新工具 pg_receivexlog 用来收集 WAL 文件的改动
增加 SP-GiST (Space-Partitioned GiST) 索引访问方法
支持 range data types
增加 JSON 数据类型
为视图增加 security_barrier 选项
允许 libpq 连接字符串使用 URI 格式
为 libpq 增加 single-row processing mode 以更好的处理大结果集。
9.2版新特性列表
(2012年9月发布)中引入的主要特性如下:
1.支持索引内查询。如果查询的列都位于索引内,那么PG会省略不必要的表访问动作,仅依据索引自身数据就可以完成全部查询动作。该优化会给键值查询以及类似COUNT(*)这种聚合查询带来巨大的性能提升。
2.内存排序操作性能提升可达20%。
3.在预处理语句中做了一些改进。现在会对预处理语句进行解析、分析和重写,但可以跳过该计划来避免被绑定到特定实参输入上。现在还可以保存依赖实参的某个预处理语句的计划。这样会降低预处理语句比等效的即席查询执行得更差的几率:语句的PREPARE预解析机制有改进。在之前版本中进行PREPARE操作时规划器会对预解析的语句生成执行计划,但由于此时的语句中不携带具体的选项值(预提交的语法形式如PREPARE ry_stmtAS select a fron tab where b=$1 and c>$2),因此规划器会基于表的统计信息来进行推测,并生成一个通用的、比较保守的执行计划,这往往会导致得到的执行计划并非最优,从而出现语句经过预解析后再执行反而比直接执行更慢的情况。为解决此问题,当前版本中的PREPARE操作有所变化,仍然会执行语句解析、语句分析、语句改写这几个过程,但会跳过生成执行计划这一步骤,留到语句EXECUTE阶段根据真正的选项再生成执行计划,这样就保证了执行计划是最优的。但这带来的另一个问题就是EXECUTE效率降低,因为每次都要生成执行计划。为此系统做了另一个优化:如果EXECUTE阶段生成的执行计划与原来在PREPARE阶段生成的通用执行计划效率类似,那么系统还是会将通用执行计划存储下来并复用。通过以上策略,避免了有时执行预提交的语句反而更慢的情况。
4.支持级联流式复制,即支持从一个 slave节点到另一个slave节点的流式复制。
5.支持基于空间分区树算法的SP-GiST索引,这种索引是GiST索引的强化版本,对于很多依赖GiST索引的扩展包来说,使用这种索引可以得到巨大的性能提升。
6.新增了对 ALTER TABLE IF EXISTS语法的支持,修改表结构之前可以不用再检查此表是否存在。
7.ALTER TABLE 和 ALTER TYPE 这两个命令新增了大量功能选项,本来要实现这些功能的话需要删除表并重建。更多细节请参见 depesz博客网站的“More Alter Table Alter Types"这篇博文。
8.增加了更多的pg _dunp和 pg_restore选项。细节请参见“9.2版中p9_durp工具的增强”。
9.新增了对PLV8语法扩展包的支持,以后可以使用目前非常流行的 JavaScript 语言来编写函数。
10.JSON正式成为系统内置数据类型,同时转正的还有row_to_json和array_to_json函数。使用Ajax的Web开发人员应该会很欢迎该特性。
11.新增了对区间数据类型的支持,不再需要通过编写函数来实现类似功能。区间类型虽然是首次引入,但系统为其提供了丰富的运算符和配套函数。Exclusion类型的约束可以很好地保证该类型数据的合法性。
12.支持在SOL函数中通过实参名称引用实参,之前版本仅支持通过实参编号引用实参。有多个实参时通过实参名称引用会更方便。
性能与扩展性改进
在9.2版本中,线性扩展性将支持64核,并增加了仅索引扫描(index-only scans)减少了CPU消耗,这意味着它在应对大多数工作负载时将对扩展性和开发者灵活性实现极大的提升。据了解,目前美国联邦航空管理局、Heroku.com都使用了PostgreSQL作为后端数据库,另外惠普公司也用它支撑远程支持软件并捆绑到HP-UX/Itanium解决方案中。增强的垂直扩展能力使得PostgreSQL能够更高效地利用大型服务器的硬件资源。锁管理、写入效率、仅索引访问以及其他底层操作使得数据库引擎可以处理更大型的工作负载。体现在数字上,这意味着:
每秒钟35万次读查询(4倍性能提升)
针对数据仓库查询的仅索引扫描性能提升2-20倍
每秒写入14000条数据(5倍性能提升)
此外级联复制功能还可以让9.2跑在更大型的服务器集群当中。
更灵活的开发者支持
PostgreSQL的灵活性表现在许多组织都能够使用它来支撑关键业务应用,从NASA到芝加哥商品交易所再到社交新贵Instagram。最新的PostgreSQL 9.2提供了对Range Types和JSON的支持,为开发者提供了更多的思路和使用方式。原生JSON数据类型的支持受到了普遍的关注,9.2中查询结果可以返回JSON类型。外加新的PL/V8 Javascript、PL/Coffee数据库编程扩展以及可选的HStore KV存储,用户现在甚至可以将PostgreSQL作为一个NoSQL文档型数据库,同时还能够保持原有的稳定性、灵活性和性能。
在PostgreSQL 9.2 发行的前几天的2010年7月下旬,Robert Haas提交了一个名为JSON for 9.2的补丁,欲将JSON列为PostgreSQL的核心类型。该补丁功能是对文本进行解析,确保它是有效的JSON数据,并加以存储。这个功能原本打算在9.2版本中放弃的,不过考虑了下发现Robert的补丁太小了点,因此决定继续并又添加了一些功能,包括:query_to_json()、array_to_json()以及record_to_json(),完成了从ProstgreSQL生成JSON数据。以下是来自测试中的一些简单示例:
SELECT query_to_json('select x as b, x * 2 as c from generate_series(1,3) x',false);
query_to_json
---------------------------------------------
[{"b":1,"c":2},{"b":2,"c":4},{"b":3,"c":6}]
(1 row)
SELECT array_to_json('{{1,5},{99,100}}'::int[]);
array_to_json
------------------
[[1,5],[99,100]]
(1 row)
-- row_to_json
SELECT row_to_json(row(1,'foo'));
row_to_json
---------------------
{"f1":1,"f2":"foo"}
(1 row)
更简单一点的:
SELECT row_to_json(q)
FROM (SELECT $$a$$ || x AS b,
y AS c,
ARRAY[ROW(x.*,ARRAY[1,2,3]),
ROW(y.*,ARRAY[4,5,6])] AS z
FROM generate_series(1,2) x,
generate_series(4,5) y) q;
row_to_json
--------------------------------------------------------------------
{"b":"a1","c":4,"z":[{"f1":1,"f2":[1,2,3]},{"f1":4,"f2":[4,5,6]}]}
{"b":"a1","c":5,"z":[{"f1":1,"f2":[1,2,3]},{"f1":5,"f2":[4,5,6]}]}
{"b":"a2","c":4,"z":[{"f1":2,"f2":[1,2,3]},{"f1":4,"f2":[4,5,6]}]}
{"b":"a2","c":5,"z":[{"f1":2,"f2":[1,2,3]},{"f1":5,"f2":[4,5,6]}]}
(4 rows)
更详细介绍和移植指南请看官方发行说明。
2013年9月上旬官宣 PostgreSQL 9.3 正式版发布了,该版本包含可写的外部数据封装、数据页 checksums、快速的故障转移以及 streaming-only remastering 等等。外部数据封装可写使得系统间支持双路数据交换。今天非常复杂的IT环境涉及到多个数据库和半结构化的数据源,而PG可帮你将它们集成在一起。该项目同时发布了postgres_fdw ,这是一个高性能的支持读写的联合驱动程序。此外,该版本提升了可靠性和可用性,实现了快速的故障转移;数据页的checksum。此外在复杂的复制环境中,可在故障发生时迅速转移主数据节点。在针对开发者方面改进包括:
额外的 JSON 构建和解析方法
自动可更新的视图与LATERAL JOINs
并行 pg_dump 用于加速大数据库的备份
9.3版新特性列表
(发布于2013年)中引入的主要特性如下:
1.增加了对 ANSI SOL 的标准LATERAL子句的支持。LATERAL语法允许将FROM子句与关联一起使用以引用关联的另一方上的变量。在一个关联查询语句中,如果参与关联的一方是一个临时结果集,比如一个子查询或者一个能够返回结果集的函数,那么在该子查询或者函数中可以引用关联关系另一方结果集中的列。如果没有LATERAL语法,这种横向关联是不可能的,只有WHERE关联条件部分才能进行被关联方之间列的交叉引用。如果需要使用unnest、generate_series或者以正则表达式作为查询条件的查询语句来构造关联一方的结果集,那么LATERAL语法几乎是不可或缺的,因为这种情况下势必要参考关联关系另一方的数据才能生成自己一方的数据。
2.支持并行pg_durmp。从8.4版开始支持并行恢复,在该版本中实现了对并行备份的支持,这可以大大加快大型数据库的备份速度。
3.支持物化视图可以将经常使用的视图中的数据进行持久化,从而避免反复执行相同的查询。
4.支持自动可更新视图。对视图执行更新操作不再需要创建触发器或者规则,现在可以直接针对视图执行UPDATE操作,该操作在系统内部会自动映射到此视图的基表上。
5.支持定义基于递归CTE表达式的视图。
6.支持更多针对JSON类型的构造函数和解析函数;支持在基于正则表达式条件的查询中使用索引。
7.引入了支持64位大对象操作的API,该API可操作TB级大小的对象。之前最多支持到2GB。
8.postgres_fdw驱动程序支持对其他PostgreSQL数据库(即使在使用较低版本PostgreSQL的远程服务器上)进行读写操作。伴随此更改的是对实施可写功能的FDW API的升级。
9.复制功能做了大量改进,其中最主要的两点是:实现了复制功能的架构无关性,即复制的架构不依赖于特定的操作系统或者硬件;另外支持了基于流式复制的重新选主过程。
10.支持使用C语言创建后台工作线程,可用于执行一些定时任务。
11.支持对DDL操作定义触发器。
12.支持新的psql命令:watch。
13.支持新的COPY DATA命令,可用于 PostgreSQL 与外部程序之间导入或者导出数据。
更多详细介绍请看发行说明。
PostgreSQL 全球开发组于2015年1月是旬宣布 PostgreSQL 9.4 正式版发布了,该版本添加很多新特性,增强了 PG 的灵活性、伸缩性和提升了整体性能。同时改进对 JSON 的支持,增强了复制和索引的性能。9.4 引入对 JSONB 的支持;新版本的逻辑解码提供了新的 API 用于新的复制工具,例如双向复制支持多个 master 节点的集群方式,同时提供复制间隙和时延复制,改进了复制的管理。此外 PG 9.4 在性能方面也做了很多提升,包括如下几个方面:
改进 GIN 索引,体积缩小 50%,速度提升 3 倍
并发更新物化视图速度更快,更及时的报告
使用 pg_prewarm 重启时快速重载数据库缓冲
更快的并发写 PG 事务日志
支持 Linux 大内存页面
9.4版新特性列表
物化视图特性的改进,在9.3版中刷新物化视图期间会对其加锁并禁止访问。但一般来说刷新物化视图会需要一定的时间,因此在生产环境中该刷新动作会导致物化视图可用性显著降低;9.4版中取消了刷新时的加锁动作,因此即使是正在被刷新的物化视图也可被访问。但请注意:利用此特性的前提是物化视图必须要拥有一个唯一索引。
新增了对SQL:2008标准中规定的percentile_disc(不连续百分比)和percentile_cont(连续百分比)这两个分析函数的支持,须配合WITHIN GROUP(ORDER BY...)子句使用。详细例子可参见depesz博客网站的一篇关于ORDERED SET WITHIN GROUP聚合运算的介绍文章。这些函数提供了系统原生的快速取中间值功能。例如希望从一批考试成绩中取中间点到3/4处部分的值,可执行以下查询:
SELECT subject,percentile_cont(ARRAY[0.5,0.75])
WITHIN GROUP (ORDER BY score) As med_75_score FROM test_scores GROUP BY subject;
在PG中要实现percentile_cont和percentile_disc,可以取一个数组或0到1之间的单个值(此值代表所希望查询的百分比范围),并且此实现会相应地返回一个值数组或单个值。语句中的ORDER BY score表示希望根据score字段的值来进行百分比计算。
创建视图时支持WITH CHECK OPTION子句,其作用是确保在视图上执行更新或者插入操 作时,修改后或者新插入的记录仍然是在本视图可见范围内。
新增对jsonb数据类型的支持,该数据类型是JSON (JavaScript Object Notation)类型的二进制存储版本,并且支持索引。通过jsonb类型可以对JSON格式的文档数据建立索引,并可加快对其内部元素的访问速度。可参考这两篇博客文章:“引入新的 jsonb数据类型:JSON类型的结构化存储格式”以及“jsonb:通配符查询”。
GIN索引的查询速度提升,同时占用空间减少。GIN索引的使用范围日益广泛,并且非常适用于全文搜索、三连词处理、hstore键值数据库以及jsonb类型支持等场景。在很多情况下你甚至可以把它当作B-树索引的一个替代品,而且一般来说GIN索引占用的空间会更少。详情请参见“使用GIN索引来代替位图索引”这篇文章的介绍。.
支持更多JSON函数。请参见Depesz博客站的文章“9.4版中的新JSON函数介绍”。
支持使用以下语法轻松地将所有资产从一个表空间移动到另一个表空间中:ALTER
TABLESPACE old_space MOVE ALL TO new_space;。
支持对返回的结果集中的记录加上数字编号。当从数组、hstore、复合类型等格式数据源中取出非格式化数据时,由于缺少可用于唯一标识记录的主键,因此一般需要为每条记录加一个数字型的行号。现在可以将系统列ordinality(该列是在ANSI SQL标准中定义的)添加到输出。以下是一个使用hstore对象以及返回一个键值对的each 函数的例子:
SELECT ordinality, key, value
FROM each('breed=>pug,cuteness=>high'::hstore) WITH ordinality;
支持通过执行SOL命令来更改系统配置设置。ALTER system SET ... 语法可实现对全局系统设置的动态修改,这一功能在之前版本中只能通过修改 postgresql.conf文件才能实现。
支持对外部表建触发器。通过该功能,即便外部数据源与你相隔万里之遥,只要对方一修改数据,你立即就可以得到通知。不过目前尚不确定该功能的实际使用效果到底如何,因为在数据源极其遥远的情况下由于存在网络延迟,其效果就很难说了。
新增unnest函数,该函数以可预见的方式将不同大小的数组分配到各个列中。
新增ROWS FROM语法,该语法可以将多个函数返回的结果集逐行拼接起来,最后作为一个完整的结果集返回,因此即使这些结果集之间的元素个数不一致也没关系,如下例所示:
SELECT * FROM ROWS FROM (
jsonb_each('{"a" : "foo1", "b" : "bar"}'::jsonb),jsonb_each('{"c": "foo2"}'::jsonb)) x (a1,a1_val,a2_val);
支持使用C对动态后台工作线程进行编码以按需完成工作。contrib/worker_spi目录下的9.4版源码中实现了一个小型的示例可供参考。
更多信息请参考此处。
--------------------------------
Postgres 9.4 Feature Highlight - WITH ORDINALITY
9.4 is going to be shipped with a feature of the SQL standard called WITH ORDINALITY. Introduced by this commit:
Author: Greg Stark <stark@mit.edu>
Date: Mon Jul 29 16:38:01 2013 +0100
Add SQL Standard WITH ORDINALITY support for UNNEST (and any other SRF)
Author: Andrew Gierth, David Fetter
Reviewers: Dean Rasheed, Jeevan Chalke, Stephen Frost
SELECT * FROM generate_series(4,1,-1) WITH ORDINALITY;
The default column name called “ordinality”, but it is possible to associate an alias to it, like that for example:
SELECT t.* FROM json_object_keys('{"a1":"1","a2":"2","a3":"3"}') WITH ORDINALITY AS t(keys,n);
This feature is actually pretty useful when used with arrays when decomposing them with unnest().
SELECT * from unnest(array[array[14,41,7],array[54,9,49]]::int[]) WITH ORDINALITY AS t(elts,num);
And it is actually far more interesting with the new feature called ROWS FROM (or multi-argument unnest), because you can associate a counter usable for some ORDER BY operations easily with that.
SELECT * FROM unnest('{1,2,3}'::int[], '{4,5,6,7}'::int[]) WITH ORDINALITY AS t(a1, a2, num) ORDER BY t.num DESC;
PGv9.4开始支持SQL标准中的WITH ORDINALITY写法,用来返回记录的每一行行号。当 from语句后面的函数加上 WITH ORDINALITY 属性后,那么返回的结果集将增加一个整数列,这个整数列从 1 开始,并且按 1 递增。
注意:WITH ORDINALITY必须使用在from子句中,且要紧跟在函数后面使用!目前不支持返回record类型的函数。
# select * from unnest(array['f','r','e','e','o','a']) with ordinality;
unnest | ordinality
----+----
f | 1
r | 2
e | 3
e | 4
o | 5
a | 6
# select * from generate_series(2,5,2) with ordinality;
generate_series | ordinality
---+---
2 | 1
4 | 2
# select * from generate_series(2,5,2) with ordinality as f(id,ord);
# select * from (values (1),(2),(3)) v(r) LEFT JOIN generate_series(11,13) with ordinality as f(i,o) ON (r+i)<100;
r | i | o
---+---+---
1 | 11 | 1
1 | 12 | 2
1 | 13 | 3
2 | 11 | 1
2 | 12 | 2
2 | 13 | 3
3 | 11 | 1
3 | 12 | 2
3 | 13 | 3
ROWS FROM
9.4 is the WITH ORDINALITY ANSI-SQL construct. What this construct does is to tack an additional column called ordinality as an additional column when you use a set returning function in the FROM part of an SQL Statement.
Basic WITH ORDINALITY
SELECT * FROM unnest('{my,dog, eats, dog food}'::text[]) WITH ordinality;
unnest | ordinality
----------+------------
my | 1
dog | 2
eats | 3
dog food | 4
If you aren't happy with the default column names, you can change them by revising your query like this:
SELECT f.* FROM unnest('{my,dog, eats, dog food}'::text[]) WITH ordinality As f(phrase, sort_order);
phrase | sort_order
----------+------------
my | 1
dog | 2
eats | 3
dog food | 4
LATERAL WITH ORDINALITY
The greatest value of WITH ORDINALITY comes when you apply it to rows of data. How do you do that when you need to use WITH ORDINALITY. This is where one of our favorite constructs, the LATERAL construct comes to the rescue.
First let's construct our table with a text array column for demonstration. Note that the fish has no tags.
CREATE TABLE pets(pet varchar(100) PRIMARY KEY, tags text[]);
INSERT INTO pets(pet, tags)
VALUES ('dog', '{big, furry, friendly, eats steak}'::text[]),
('cat', '{small, snob, eats greenbeans, plays with mouse}'::text[]),
('mouse', '{very small, fits in pocket, eat peanuts, watches cat}'::text[]),
('fish', NULL);
If you do a cross join, you'll leave out fish because he's got no tags:
SELECT pet,sort_order,tag FROM pets,unnest(tags) WITH ORDINALITY As f(tag,sort_order);
In order to include pets that have no tags, you need to do a LEFT JOIN like so:
SELECT pet,sort_order,tag FROM pets LEFT JOIN
LATERAL unnest(tags) WITH ORDINALITY As f(tag,sort_order) ON true;
继续来看实例
CREATE TABLE uns1(id int2 PRIMARY KEY, elements varchar(99));
insert into uns1(id,elements) values (1,'ab,cd,efg,hi'),(2,'jk,lm,no,pq'),(3,'rstuv,wxyz');
unnest() with element number
When I have a column with separated values, I can use the unnest() function:
id | elements
---+------------
1 |ab,cd,efg,hi
2 |jk,lm,no,pq
3 |rstuv,wxyz
select id, unnest(string_to_array(elements, ',')) AS elem from myTable;
id | elem
---+-----
1 | ab
1 | cd
1 | efg
1 | hi
2 | jk
...
How can I include element numbers? I.e.:
id | elem | nr
---+------+---
1 | ab | 1
1 | cd | 2
1 | efg | 3
1 | hi | 4
2 | jk | 1
...
I want the original position of each element in the source string. I've tried with window functions (row_number(), rank() etc.) but I always get 1. Maybe because they are in the same row of the source table?
Postgres 9.4 or later
Use WITH ORDINALITY for set-returning functions:
When a function in the FROM clause is suffixed by WITH ORDINALITY, a bigint column is appended to the output which starts from 1 and increments by 1 for each row of the function's output. This is most useful in the case of set returning functions such as unnest().
In combination with the LATERAL feature in pg 9.3+, and according to this thread on pgsql-hackers, the above query can now be written as:
SELECT t.id, a.elem, a.nr FROM tbl AS t
LEFT JOIN LATERAL unnest(string_to_array(t.elements, ',')) WITH ORDINALITY AS a(elem, nr) ON true;
LEFT JOIN ... ON true preserves all rows in the left table, even if the table expression to the right returns no rows. If that's of no concern you can use this otherwise equivalent, less verbose form with an implicit CROSS JOIN LATERAL:
SELECT t.id, a.elem, a.nr
FROM tbl t, unnest(string_to_array(t.elements, ',')) WITH ORDINALITY a(elem, nr);
--倒排
SELECT t.id, a.elem, a.nr
FROM uns1 t, unnest(string_to_array(t.elements, ',')) WITH ORDINALITY a(elem,nr) order by t.id,a.nr desc;
Or simpler if based off an actual array (arr being an array column):
insert into table2 select id,string_to_array(elements,',') from table1;
SELECT t.id, a.elem, a.nr FROM tbl t, unnest(t.arr) WITH ORDINALITY a(elem, nr);
Or even, with minimal syntax:
SELECT id, a, ordinality FROM tbl, unnest(arr) WITH ORDINALITY a;
a is automatically table and column alias. The default name of the added ordinality column is ordinality. But it's better (safer, cleaner) to add explicit column aliases and table-qualify columns.
Postgres 8.4 - 9.3
With row_number() OVER (PARTITION BY id ORDER BY elem) you get numbers according to the sort order, not the ordinal number of the original ordinal position in the string.
Can simply omit ORDER BY:
SELECT *, row_number() OVER (PARTITION by id) AS nr
FROM (SELECT id, regexp_split_to_table(elements, ',') AS elem FROM tbl) t;
select v.*, row_number() over (partition by id order by elem) rn from
(select id,unnest(string_to_array(elements, ',')) AS elem from uns1) v
While this normally works and I have never seen it fail in simple queries, PostgreSQL asserts nothing concerning the order of rows without ORDER BY. It happens to work due to an implementation detail.
To guarantee ordinal numbers of elements in the blank-separated string:
SELECT id, arr[nr] AS elem, nr
FROM (SELECT *, generate_subscripts(arr, 1) AS nr FROM (SELECT id, string_to_array(elements, ' ') AS arr FROM tbl) t
) sub;
Or simpler if based off an actual array:
SELECT id, arr[nr] AS elem, nr FROM (SELECT *, generate_subscripts(arr, 1) AS nr FROM tbl) t;
Postgres 8.1 - 8.4
Skip...
PostgreSQL 9.5于2016年1月7日正式发布,此版本主要带来了以下几个方面的特性: UPSERT, Row Level Security, and Big Data。下面是新特性的用法示例,更多的特性可以参考PDF文档。
该版本主要在性能方面有很大的提升,也包括一些新的 SQL 特性以及复制支持方面,主要内容包括:
允许查询直接从索引中获取数据,避免访问堆数据 (index-only scans)
允许查询计划器为指定参数值生成自定义的计划,甚至是用了 Prepared Statement
提升计划器通过内部索引扫描来使用嵌套循环
允许流复制从节点将数据转到其他从节点 (cascading replication)
允许 pg_basebackup 对待机的服务器进行基准备份
增加新工具 pg_receivexlog 用来收集 WAL 文件的改动
增加 SP-GiST (Space-Partitioned GiST) 索引访问方法
支持 range data types
增加 JSON 数据类型
为视图增加 security_barrier 选项
允许 libpq 连接字符串使用 URI 格式
为 libpq 增加 single-row processing mode 以更好的处理大结果集。
这一系列版本都是为了修复同一个高危的安全漏洞(CVE-2013-1899),强烈建议所有用户立即升级!此外这次更新还包括其他安全问题以及 bug 的修复,更多详情请看发行说明。
1)、UPSERT
UPSERT是INSERT, ON CONFLICT UPDATE的简写,简而言之就是:插入数据,正常时写入,主键冲突时更新。下面给个简单的例子:
--创建测试表,并插入一条数据。
CREATE TABLE customer (cust_id INTEGER PRIMARY KEY, name TEXT);
INSERT INTO customer VALUES (100, ’Big customer’);
--常规INSERT语句,主键冲突,报错。
INSERT INTO customer VALUES (100, ’Non-paying customer’);
ERROR: duplicate key value violates unique constraint
"customer_pkey"
DETAIL: Key (cust_id)=(100) already exists.
--新特性,主键冲突时,自动更新数据。
INSERT INTO customer VALUES (100, ’Non-paying customer’)
ON CONFLICT (cust_id) DO UPDATE SET name = EXCLUDED.name;
SELECT * FROM customer;
cust_id | name
---------+---------------------
100 | Non-paying customer
2)、Row Level Security
行级安全控制:
--创建测试表,并开启行级别安全策略
CREATE TABLE orders (id INTEGER, product TEXT,
entered_by TEXT);
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
CREATE POLICY orders_control ON orders FOR ALL TO PUBLIC
USING (entered_by = CURRENT_USER);
GRANT ALL ON TABLE orders TO PUBLIC;
--创建两个用户
CREATE USER emp1;
CREATE USER emp2;
--分别插入一条数据
SET SESSION AUTHORIZATION emp1;
INSERT INTO orders VALUES (101, ’fuse’, CURRENT_USER);
SET SESSION AUTHORIZATION emp2;
INSERT INTO orders VALUES (102, ’bolt’, CURRENT_USER);
--使用超级用户,可以看到所有纪录。
SET SESSION AUTHORIZATION postgres;
SELECT * FROM orders;
id | product | entered_by
-----+---------+------------
101 | fuse | emp1
102 | bolt | emp2
--普通账号只能看到自己的纪录。
SET SESSION AUTHORIZATION emp1;
SELECT * FROM orders;
id | product | entered_by
-----+---------+------------
101 | fuse | emp1
SET SESSION AUTHORIZATION emp2;
SELECT * FROM orders;
id | product | entered_by
-----+---------+------------
102 | bolt | emp2
3)、Big Data
3.1)、BRIN Indexing
一种占用空间特别小的索引,适合超大数据量且自然排序(如:id递增)的表。
CREATE TABLE brin_example AS
SELECT generate_series(1,100000000) AS id;
CREATE INDEX btree_index ON brin_example(id);
CREATE INDEX brin_index ON brin_example USING brin(id);
SELECT relname, pg_size_pretty(pg_relation_size(oid))
FROM pg_class
WHERE relname LIKE ’brin_%’ OR relname = ’btree_index’
ORDER BY relname;
relname | pg_size_pretty
--------------+----------------
brin_example | 3457 MB
btree_index | 2142 MB
brin_index | 104 kB
--以上三行是关键,看大小!!!
3.2)、Faster Sorts
使用了一种叫做“abbreviated keys”的算法,使得对varchar()、text和NUMERIC()几种类型排序更快,查询提速2~12倍,索引创建提速20倍。
3.3)、CUBE, ROLLUP and GROUPING SETS
聚集函数类sql更好写了,OLAP更方便。示例代码例子太长,就不贴了。
3.4)、Foreign Data Wrappers (FDWs)
外部数据包装,示例代码:
--以前得这个写
CREATE FOREIGN TABLE remote.customers (
id int NOT NULL,
name text,
company text,
registered_date date,
expiry_date date,
active boolean,
status text,
account_level text) SERVER dest_server OPTIONS (schema_name 'public');
CREATE FOREIGN TABLE remote.purchases (
id int NOT NULL,
purchase_time timestamptz,
payment_time timestamptz,
itemid int,
volume int,
invoice_sent boolean) SERVER dest_server OPTIONS (schema_name 'public');
--9.5可以这么写
IMPORT FOREIGN SCHEMA public FROM SERVER dest_server INTO remote;
--其它写法
IMPORT FOREIGN SCHEMA public
EXCEPT (reports, audit)
FROM SERVER dest_server INTO remote;
IMPORT FOREIGN SCHEMA public
LIMIT TO (customers, purchases)
FROM SERVER dest_server INTO remote;
3.5)、TABLESAMPLE
方便对数据进行抽样。
--抽样10%数据
select * from ts_test tablesample system(10);
PostgreSQL越来越强大了,种种迹象来看(BRUCE MOMJIAN说的),PostgreSQL正在朝着多方向发展:
1)Big data大数据:BRIN的支持,Foreign Data Wrappers支持
2)Data analytics 数据分析:grouping sets, cube, rollup的支持
3)Large servers :Faster Sorts,Hashing性能改善,多核大内存支持更好,比如:IBM POWER-8, having 24 cores, 192 hardware threads, and 492GB RAM环境下,TPS达到40万
4)NoSQL:JSONB相关支持,单机性能是MongoDB的好几倍。
参考来源:
PostgreSQL 9.5 有哪些新特性
Gulcin Yildirim: Tablesample In PostgreSQL 9.5
PostgreSQL9.5 给开发人员带来了什么?
PostgreSQL全球开发者在2016年9月29日宣布其最新版本9.6正式发布。此版本将允许用户纵向扩展(scale-up)和横向扩展(scale-out)来提高数据库的查询性能。新功能包括并行查询、同步复制改进、短语搜索、性能和易用性方面的改进,并提供了其它许多方面的功能。
纵向扩展的并行查询
9.6版本现支持一些并行查询操作,因而能够利用服务器上的几个或所有的CPU内核来进行运算,这样返回查询结果更快。此版本的并行功能包括并行顺序表扫描、聚合和联接。根据详细信息和可用内核,并行性可以加快大数据查询,最快时可高达32倍。Synthetic Genomics的首席数据库架构师Mike Sofen表示, “我们将我们整个基因组数据平台–250亿行旧的MySQL数据迁移到一个Postgres数据库, 利用了 JSONB 数据类型的行压缩功能,以及优秀的GIN,BRIN和B-Tree索引模式。期待在9.6版本中,利用并行查询功能,在我们查询大表数据时,拥有更强劲的伸缩性,更优的查询性能”
横向扩展的同步复制与postgres_fdw
PostgreSQL的同步复制功能添加了两个选项,使它能够用于数据库集群一致读取维护。首先,它现在允许配置一组的同步的复制数据库。其次,“remote_apply”模式创建多个跨数据节点的一致的读视图。这些功能使用内置的复制来维护一组的“相同的”节点实现,可以用于数据库的读负载均衡。postgres_fdw(PostgreSQL-to-PostgreSQL数据外部表驱动程序)提供了新的功能,支持在远程服务器上执行操作。通过“下推”(Push Down)排序(sort),Join联接,批量数据更新(update)任务, 用户可以调度多个PostgreSQL服务器来完成数据查询。这些功能很快会添加到其他fdw模块中。Equnix商务解决方案主管Julyanto Sutandang表示,“fdw支持远程联接,更新和删除的功能,是当下其他数据库和 PostgreSQL共享数据的完整解决方案,比如可以实现所录入的数据保存到两个或多个不同类型的数据库的功能”
更好的文本短语搜索
PostgreSQL的全文搜索功能,现在支持短语搜索。这允许用户搜索精确的短语,或是搜索有一定相似性的短语,使用快速的GIN索引中的单词,结合可精细调整的文本搜索选项的新功能,PostgreSQL是“混合搜索”的超优选择,集成了关系表,JSON和全文的搜索支持。
更畅、更快和更易使用
感谢大批PostgreSQL用户使用他们的包含大量数据生产数据库来进行PostgreSQL的反馈和测试,这个版本包括了大量有关性能提升和可用性等方面的内容。复制、聚合、索引、排序和存储过程变得更加高效,在新的Linux内核上,PostgreSQL现在可以可以更好的利用资源,降低了大型表查询和复杂查询的系统负载,尤其是VACUUM的改进。
9.6版本累计近一年来的很多新特性,主要包括︰
新的系统视图和函数:pg_stat_wal_receiver,pg_visbility,pg_config,pg_blocking_pids,pg_notification_queue_usage
支持命令执行进度状态报告
支持级联操作(需安装扩展模块实现)
支持pg_basebackup的并发
逻辑复制插槽
等待事件支持
在psql中编辑视图和crosstabs
用户定义旧快照过期
只扫描局部索引
此外该版本改进并优化了热备流复制的API,这样开发人员可以用自定义的备份工具测试PostgreSQL新版本。更多详细信息请参阅完整发布说明。
并行方式全表扫描功能已提交 PostgreSQL 9.6 版主干代码
2016年1月中旬消息,建议过将并行全表扫描功能加入至PostgreSQL 9.5中,但未实现。现在很高兴地向各位通报已经将第一版本的并行扫描功能提交至PostgreSQL的开发主分支中,确认它将会包含在将要发布的9.6版本中。为PostgreSQL增加并行查询功能,目前这只是第一步,它也是长久以来的一个梦想,已为此工作了好几年了,最早真正开发时是在9.4版本的开发期间,那时主要是开发了一些后台动态进程和动态共享内存;接着在9.5版本期间,又增加了很多有关并行机制的底层基本加松的开发,以及其他包含在提交的补丁的内容。下面想说提交的 主要内容明细和下一步还准备要开发的工作和大家沟通一下。
在开始之前,想首先将这些荣誉给一些应该得的人。首先,Amit Kapila为这个项目中贡献了巨大的帮助。主要是由Amit和我写了这个功能的大部分代码,这些代码经过涵盖在最近几年多次提交的补丁中。我们俩也写了大量的没有包含在补丁 中的代码。第二,我想感谢Noah Misch,在项目早期阶段,在被一些问题给绕得晕头转向时,他给了我很大的帮助;第三,想向整个PostgreSQL社区的成员,尤其是所有帮助我进行代码审核、功能测试、提出改进意见以及在很多其他方面提供帮助而最终使用这个功能得以实现的人们。
最为重要的是,我要感谢EnterpriseDB公司,没有该公司管理上的支持,尤其是来自Tom Kincaid和Marc Linster的支持,也就不可能让我和Amit有大量的时间开发并最终完成这个项目。同样地,没有我在EnterpriseDB公司的团队的支持,我们的项目也不可能现在完成,当我忙于项目开发时,我的同事们耐心地帮助我处理了其他的问题。谢谢所有的人。
好了,现在来看一下测试效果:
rhaas=# \timing
Timing is on.
rhaas=# select * from pgbench_accounts where filler like '%a%';
aid | bid | abalance | filler
-----+-----+----------+--------
(0 rows)
Time: 743.061 ms
rhaas=# set max_parallel_degree = 4;
SET
Time: 0.270 ms
rhaas=# select * from pgbench_accounts where filler like '%a%';
aid | bid | abalance | filler
-----+-----+----------+--------
(0 rows)
Time: 213.412 ms
这里是查询计划的内容:
rhaas=# explain (costs off) select * from pgbench_accounts where filler like '%a%';
QUERY PLAN
---------------------------------------------
Gather
Number of Workers: 4
-> Parallel Seq Scan on pgbench_accounts
Filter: (filler ~~ '%a%'::text)
(4 rows)
目前因该功能还在进一步的开发中,还有一些未处理的问题和使用限制,如现在该功能暂不能在分区表上使用;
仅可对表的全表扫描类查询较有效,有索引的列就用不上了,当然对数据的过滤的操作,多进程并行处理总是要快一些;还有就是并行处理的进程数如何根据系统配置进行最有效设置,以及其他一些小问题还未完全完成。最后请大家多多进行测试,并给我们反馈Bug,谢谢!
以上博文翻译自PostgreSQL主要代码贡献人员之一Robert Haas的博客(详情可浏览此处),同时他也是并行方式全表扫描功能的主要开发人员(原文地址)。
该文章最后由 阿炯 于 2024-01-13 16:40:31 更新,目前是第 7 版。