2. 分區表的改進
PostgreSQL 10 實現了聲明式分區,PostgtreSQL 11完善了功能,PostgreSQL 12提升了性能。我們知道在PostgreSQL 9.X時代需要通過表繼承實現分區,這時還需要手工加觸發器或規則把新插入的數據重新定向到具體的分區中,從PostgreSQL 10之后不需要這樣了,直接用聲明式分區就可以了,語法如下:
CREATE TABLE measurement (
city_id int not null,
logdate date not null,
peaktemp int,
unitsales int
) PARTITION BY RANGE (logdate);
CREATE TABLE measurement_y2006m02 PARTITION OF measurement
FOR VALUES FROM ('2006-02-01') TO ('2006-03-01');
分區表更具體的一些變化如下:
-
PostgreSQL11: 分區表增加哈希分區
-
PostgreSQL11:分區表支持創建主鍵、外鍵、索引、觸發器
-
PostgreSQL11: 分區表支持UPDATE分區鍵,如果在分區表上創建了一個索引,PostgreSQL 自動為每個分區創建具有相同屬性的索引。
-
PosgtreSQL 11 支持為分區表創建一個默認(DEFAULT)的分區
-
對於 PostgreSQL 10 中的分區表,無法創建引用其他表的外鍵約束。 PostgreSQL 11 解決了這個限制,可以創建分區表上的外鍵。
-
在 PostgreSQL 10 中,分區上的索引需要基於各個分區手動創建,而不能基於分區的父表創建索引。PostgreSQL 11 可以基於分區表創建索引。如果在分區表上創建了一個索引,PostgreSQL 自動為每個分區創建具有相同屬性的索引。
- PostgreSQL 12后: ALTER TABLE ATTACH PARTITION不會阻塞查詢
3. PostgreSQL 10版本的功能增強
3.1 PostgreSQL 10 新功能總結如下:
-
支持同步復制多個standby:Quorum Commit
-
PostgreSQL 10開始增加聲明式分區
-
PostgreSQL 10 增加了並行功能
-
PostgreSQL 10之后 hash索引可以走流復制,從此可以大膽的使用hash索引了。
-
PostgreSQL 10之后提供了邏輯復制的功能:發布訂閱的功能
-
PostgreSQL 10可以把多列組合在一起再建直方圖,讓一些關聯列上的執行計划更准確
-
可以支持同步復制到多個standby,即Quorum Commit
- 以前的密碼驗證式md5,現在增加了安全級別更高的密碼驗證的方式:SCRAM-SHA-256
3.2 並行查詢功能:
- 實際上從9.6開始就有並行查詢功能,但功能比較弱,到PostgreSQL 10版本之后,功能大大增強,后續的每個大版本或多或少都有功能增強。
-
並行的參數
- max_parallel_workers=16;
- max_parallel_workers_per_gather =4;
- min_parallel_table_scan_size:只有表的大小大於此值時才需要並行,默認為8M,可以設置為1G或更大的值。
-
保持與9.X相同的行為,可以關閉並行
- set max_parallel_workers_per_gather = 0
- 當需要並行時,可以手工設置max_parallel_workers_per_gather的值
- max_parallel_maintenance_workers
3.3 邏輯復制功能
邏輯解碼實際上是在PostgreSQL 9.4開始准備的功能,在9.X時代,支持內置了邏輯解碼的功能,如果要做兩個數據庫之間表數據的邏輯同步,需要自己寫程序或使用一些開源的軟件來實現。到PostgreSQL 10版本,原生提供了邏輯復制的功能,實現了邏輯發布和訂閱的功能,邏輯復制的功能變化如下:
- PostgreSQL 10版本不支持truncate的同步,導致在10版本中,作為邏輯同步的表不能做truncate。從PostgreSQL 11版本之后可以支持truncate功能。
不過PostgreSQL自帶的邏輯復制功能有以下限制:
- 邏輯解碼是在主庫上完成的,會消耗主庫的CPU
- 必須建邏輯復制槽。但是邏輯復制槽會把主庫的WAL給hold住,很多新手配置了邏輯復制,后來停掉了,但是忘記把邏輯復制槽給刪除掉,最后把主庫空間給撐爆
- 邏輯復制槽不支持備庫,如果使用流復制的高可用方案,主備庫切換后,邏輯復制就廢了。
- 大事務會在主庫中會生成一個臨時文件,如果這個事務很大,這個臨時文件也很大。
- 需要把wal_level級別設置logical,這會導致更多的WAL日志生成。
實際上中啟乘數科技開發的有商業版的邏輯復制軟件CMiner,解決了以上問題。CMiner本身是一個獨立的程序,連接到主庫上通過流復制協議拉取WAL日志,然后在本地解碼,不會消耗主庫的CPU,也不使用邏輯復制槽,沒有把主庫空間撐爆的風險,也可以方便的支持基於流復制的高可用方案,同時wal_level級別不需要設置為logical就可以完成解碼。目前這套解決方案已經在銀行中使用,有興趣同學可以加微信 osdba0,或郵件 services@csudata.com 。
3.4 相關列上建組合的直方圖統計信息
用實例說明這個功能:
create table test_t( a int4, b int4);
insert into test_t(a,b) select n%100,n%100 from generate_series(1,10000) n;
上面的兩個列a和b的數據相關的,即基本是相同的,而PostgreSQL默認計算各列是按非相關來計算了,所以算出的的COST值與實際相差很大:
osdba=# explain analyze select * from test_t where a=1 and b=1;
QUERY PLAN
----------------------------------------------------------------------------------------------------
Seq Scan on test_t (cost=0.00..195.00 rows=1 width=8) (actual time=0.034..0.896 rows=100 loops=1)
Filter: ((a = 1) AND (b = 1))
Rows Removed by Filter: 9900
Planning Time: 0.185 ms
Execution Time: 0.916 ms
如上面,估計出只返回1行,實際返回100行。這在一些 復雜SQL中會導致錯誤的執行計划。
這時我們可以在相關列上建組合的直方圖統計信息:
osdba=# CREATE STATISTICS stts_test_t ON a, b FROM test_t;
CREATE STATISTICS
osdba=# analyze test_t;
ANALYZE
osdba=# explain analyze select * from test_t where a=1 and b=1;
QUERY PLAN
------------------------------------------------------------------------------------------------------
Seq Scan on test_t (cost=0.00..195.00 rows=100 width=8) (actual time=0.012..0.830 rows=100 loops=1)
Filter: ((a = 1) AND (b = 1))
Rows Removed by Filter: 9900
Planning Time: 0.127 ms
Execution Time: 0.848 ms
(5 rows)
從上面可以看出當我們建了相關列上建組合的直方圖統計信息后,執行計划中估計的函數與實際一致了。
3.5 一些其它功能
hash索引從PostgreSQL 10開始可以放心大膽的使用:
-
PostgreSQL 9.X 版本hash索引走不了流復制,所以基本沒有人用hash索引,即如果用了hash索引,在激活備庫時,需要重建hash索引。
-
到PostgreSQL 10.X,hash索引可以通過流復制同步到備庫,所以沒有這個問題了,這是可以大膽的使用hash索引了。
到PostgreSQL 10之后,很多函數都進行了改名,其中把函數名中的“xlog”都改成了“wal”,把“position”都改成了“lsn”:
-
pg_current_wal_lsn
-
pg_current_wal_insert_lsn
-
pg_current_wal_flush_lsn
-
pg_walfile_name_offset
-
pg_walfile_name
-
pg_wal_lsn_diff
-
pg_last_wal_receive_lsn
-
pg_last_wal_replay_lsn
-
pg_is_wal_replay_paused
-
pg_switch_wal
-
pg_wal_replay_pause
-
pg_wal_replay_resume
-
pg_ls_waldir
PostgreSQL 10對一些目錄也改名:
-
Rename write-ahead log directory pg_xlog to pg_wal
-
rename transaction status directory pg_clog to pg_xact
PostgreSQL 9.X,同步復制只能支持一個同步的備庫,PostgtreSQL 10 可以支持多個同步的standby,這稱為“Quorum Commit”,同步復制的配置發生如下變化:
-
synchronous_standby_names
- FIRST num_sync (standby_name [, …]):保持前面幾個備庫必須與主庫保持同步。
- ANY num_sync (standby_name [, …]):保證num_sync 個備庫與主庫保持同步。
-
原先的配置: synchronous_standby_names=’stb01,stb02,stb03’實際相當於: synchronous_standby_names=FIRST 1(stb01,stb02,stb03)’
索引的增強:
- BRIN索引增強:
- BRIN索引增加了存儲選項autosummarize,可以自動計算摘要
- 增加了函數brin_summarize_range()和brin_desummarize_range() 可以手工為BRIN的指定塊建摘要和去除摘要。以前BRIN只有函數brin_summarize_new_values()、 gin_clean_pending_list()
- Improve accuracy in determining if a BRIN index scan is beneficial (David Rowley, Emre Hasegeli)
- INET和CIDR類型上支持建SP-GiST類型的索引
- 在GiST索引的插入和更新可以更高效的重用空間
- Reduce page locking during vacuuming of GIN indexes
串行隔離級別 預加鎖閾值可控
- max_pred_locks_per_relation: 當單個對象的行或者頁預加鎖數量達到閾值時,升級為對象預加鎖。減少內存開銷。
- max_pred_locks_per_page:當單個頁內多少條記錄被加預加鎖時,升級為頁預加鎖。減少內存開銷
PostgreSQL 10提供了視圖pg_hba_file_rules方便查詢訪問控制的黑白名單:
osdba=# select * from pg_hba_file_rules;
line_number | type | database | user_name | address | netmask | auth_method | options | error
-------------+-------+---------------+-----------+---------+---------+-------------+---------+-------
80 | local | {all} | {all} | | | peer | |
83 | host | {all} | {all} | 0.0.0.0 | 0.0.0.0 | md5 | |
88 | local | {replication} | {all} | | | peer | |
psql增加了:\if, \elif, \else, and \endif.
SELECT
EXISTS(SELECT 1 FROM customer WHERE customer_id = 123) as is_customer,
EXISTS(SELECT 1 FROM employee WHERE employee_id = 456) as is_employee
\gset
\if :is_customer
SELECT * FROM customer WHERE customer_id = 123;
\elif :is_employee
\echo 'is not a customer but is an employee'
SELECT * FROM employee WHERE employee_id = 456;
\else
\if yes
\echo 'not a customer or employee'
\else
\echo 'this will never print'
\endif
\endif
其它的一些功能:
-
提升了聚合函數sum()、avg()、stddev()處理numeric類型的性能
-
Allow hashed aggregation to be used with grouping sets
-
Improve sort performance of the macaddr data type (Brandur Leach)
-
Add pg_stat_activity reporting of low-level wait states (Michael Paquier, Robert Haas, Rushabh Lathia)
- This change enables reporting of numerous low-level wait conditions, including latch waits, file reads/writes/fsyncs, client reads/writes, and synchronous replication.
-
Show auxiliary processes, background workers, and walsender processes in pg_stat_activity (Kuntal Ghosh, Michael Paquier)
-
This simplifies monitoring. A new column backend_type identifies the process type.
-
Prevent unnecessary checkpoints and WAL archiving on otherwise-idle systems (Michael Paquier)
-
Increase the maximum configurable WAL segment size to one gigabyte (Beena Emerson)
-
Add columns to pg_stat_replication to report replication delay times (Thomas Munro)
- The new columns are write_lag, flush_lag, and replay_lag.
-
Allow specification of the recovery stopping point by Log Sequence Number (LSN) in recovery.conf (Michael Paquier)
-
Previously the stopping point could only be selected by timestamp or XID.
-
Improve performance of hot standby replay with better tracking of Access Exclusive locks (Simon Riggs, David Rowley)
-
Speed up two-phase commit recovery performance (Stas Kelvich, Nikhil Sontakke, Michael Paquier)
-
Allow restrictive row-level security policies (Stephen Frost)
-
Add CREATE SEQUENCE AS command to create a sequence matching an integer data type (Peter Eisentraut)
-
Allow the specification of a function name without arguments in DDL commands, if it is unique (Peter Eisentraut)
-
Improve speed of VACUUM’s removal of trailing empty heap pages (Claudio Freire, Álvaro Herrera)
-
Add full text search support for JSON and JSONB (Dmitry Dolgov)
-
The functions ts_headline() and to_tsvector() can now be used on these data types.
-
自增列原先只有用serial和bigserial創建自增列,現在可以標准的語法創建自增列
CREATE TABLE test01 (
id int PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
t text
);
- 增加減號為jsonb類型的刪除某個key的操作符
postgres=# select '{"a": 1, "b": 2, "c":3}'::jsonb - '{a,c}'::text[];
?column?
\----------
{"b": 2}
(1 row)
-
Allow specification of multiple host names or addresses in libpq connection strings and URIs (Robert Haas, Heikki Linnakangas)。
- libpq will connect to the first responsive server in the list.
- 配合連接參數target_session_attrs=read-write,只是只會連接到一個主庫上。
-
Allow file_fdw to read from program output as well as files (Corey Huinker, Adam Gomaa)
-
In postgres_fdw, push aggregate functions to the remote server, when possible (Jeevan Chalke, Ashutosh Bapat)
4. PostgreSQL 11版本的新特性
4.1 PostgreSQL 11版本的功能總結
總結如下:
-
JIT即時編譯功能,提升一些批計算如SUM的性能,通常提升在10%左右。
-
存儲過程中可以加commit或rollback事物
-
聲明式分區表功能大大增強: 分區表可以加主鍵、外鍵、索引,支持hash分區表
-
CREATE INDEX可以並行
-
增加非空列也是瞬間完成,不需要rewrite表
-
hash join支持並行
-
vacuum增強:空閑空間可以更快的被重用,跳過一些沒有必要的索引掃描
-
提升了多個並發事務commit的性能
- 邏輯復制支持truncate的同步
- 支持存儲過程(CREATE PROCEDURE),並可以在存儲過程中嵌入事務
- CREATE INDEX使用INCLUDE可以非鍵值列放到索引中,以便走Covering indexes而不必回表
- 以前觸發toast的壓縮都需要插入的數據大於1996個字節時才會觸發,這個1996字節是固定的,不能改,現在給表加了存儲參數 toast_tuple_target,可以設置更新的值就可以觸發toast的壓縮機制
- 允許在initdb時改變 WAL文件的大小,以前是需要重新編譯程序才能改變WAL文件的大小
- 現在在WAL日志中會把使用的部分填0,這樣可以提高壓縮率
4.2 PostgreSQL 11版本的jit
即時編譯功能:
-
常用於CPU密集型SQL(分析統計SQL),執行很快的SQL使用JIT由於產生一定開銷,反而可能引起性能下降
-
jit的參數:
- jit = on
- jit_provider = ‘llvmjit’
- jit_above_cost= 100000
4.3 PostgtreSQL一些其它增強
新的變化:
-
可以手工調整復制槽的記錄的位置:
- Allow replication slots to be advanced programmatically, rather than be consumed by subscribers (Petr Jelinek)
- This allows efficient advancement of replication slots when the contents do not need to be consumed. This is performed by pg_replication_slot_advance().
-
以前給表加有默認值的列時需要重寫文件,現在不需要了
- Allow ALTER TABLE to add a column with a non-null default without doing a table rewrite (Andrew Dunstan, Serge Rielau)
- This is enabled when the default value is a constant.
PostgreSQL 11版本的一些新特性
-
PostgreSQL11: 新增三個默認角色
-
PostgreSQL11: 可通過GRNAT權限下放的四個系統函數
-
PostgreSQL11: Initdb/pg_resetwal支持修改WAL文件大小
-
PostgreSQL11: 新增非空默認值字段不需要重寫
–ALTER TABLE table_name ADD COLUMN flag text DEFAULT ‘default values’;
-
PostgreSQL11: Indexs With Include Columns
CREATE TABLE t_include(a int4, name text);
CREATE INDEX idx_t_include ON t_include USING BTREE (a) INCLUDE (name);
-
PostgreSQL11: initdb/pg_resetwal支持修改WAL文件大小,以前需要重新編譯程序,才能改變。
PostgreSQL 10、11增加了一些 系統角色,方便監控用戶的權限:
- PostgreSQL 11 新增三個默認系統角色,如下:
- pg_read_server_files
- pg_write_server_files
- pg_execute_server_program
- PostgreSQL 10
- pg_read_all_settings
- pg_read_all_stats
- pg_stat_scan_tables
- pg_monitor
- PostgreSQL9.6只有一個系統角色:
- pg_signal_backend
PostgreSQL 11 版本的psql中增加了命令\gdesc可以查看執行結果的數據類型:
osdba=# select * from test01 \gdesc
Column | Type
--------+---------
id | integer
id2 | integer
t | text
(3 rows)
PostgreSQL 11版本psql增加了五個變量更容易查詢SQL執行失敗的原因:
- ERROR
- SQLSTATE
- ROW_COUNT
- LAST_ERROR_MESSAGE
- LAST_ERROR_SQLSTATE
使用示例如下:
osdba=# select * from test01;
id | t
----+-----
1 | 111
2 | 222
(2 rows)
osdba=# \echo :ERROR
false
osdba=# \echo :SQLSTATE
00000
osdba=# \echo :ROW_COUNT
2
osdba=# select * from test02;
ERROR: relation "test02" does not exist
LINE 1: select * from test02;
^
osdba=# \echo :ERROR
true
osdba=# \echo :SQLSTATE
42P01
osdba=# \echo :LAST_ERROR_MESSAGE
relation "test02" does not exist
osdba=# \echo :LAST_ERROR_SQLSTATE
42P01
5. PostgreSQL 12版本的新特性
5.1 新特性總結
特性如下:
-
PostgreSQL 12開始取消了recovery.conf,把配置項移動到postgresql.conf中
- 為了表明此庫是備庫,需要在$PGDATA下建standby.signal 空文件。去掉了配置項standby_mode
- 配置項trigger_file改名為promote_trigger_file
- PostgreSQL 12 只能同時配置恢復目標項的一項,不能同時配置:recovery_target, recovery_target_lsn, recovery_target_name, recovery_target_time, recovery_target_xid
- pg_stat_replication中增加了應用延遲時間字段: reply_time
-
減少了在創建GiST,GIN,SP-GiST索引的WAL日志量
- max_wal_senders 連接數從 max_connections 剝離
-
支持在線重建索引:REINDEX CONCURRENTLY
-
在Btree索引中減少了不必要的多版本數據,提升了性能。
-
PG12默認開啟了JIT
-
提升了position函數的性能
-
SERIALIZABLE事物事物隔離級別也可以並行查詢
-
VACUUM增加了選項TRUNCATE,有可能不需要vacuum full也能釋放部分空間到操作系統
- 分區表的性能得到了加強。
5.2 對VACUUM的增強:
osdba=# \h vacuum
Command: VACUUM
Description: garbage-collect and optionally analyze a database
Syntax:
VACUUM [ ( option [, ...] ) ] [ table_and_columns [, ...] ]
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, ...] ]
where option can be one of:
FULL [ boolean ]
FREEZE [ boolean ]
VERBOSE [ boolean ]
ANALYZE [ boolean ]
DISABLE_PAGE_SKIPPING [ boolean ]
SKIP_LOCKED [ boolean ]
INDEX_CLEANUP [ boolean ]
TRUNCATE [ boolean ]
and table_and_columns is:
table_name [ ( column_name [, ...] ) ]
URL: https://www.postgresql.org/docs/12/sql-vacuum.html
如上所示,增加了一些選項:
- DISABLE_PAGE_SKIPPING: 通常,VACUUM將基於可見性映射跳過頁面。如果.vm文件損壞,可以把這個參數設置為true.
- SKIP_LOCKED:跳過一給鎖定的,防止vacuum被hang
- INDEX_CLEANUP: 默認是YES。
- TRUNCATE:把一些未用連續的數據塊空間釋放給文件系統,相當與數據文件是一個稀疏文件,即在一些情況下不需要VACUUM FULL也能釋放一些空間給文件系統。
其它的一些變化:
-
PostgreSQL 12版本之后:max_wal_senders 連接數從 max_connections 剝離
-
PostgreSQL 12 版本之后支持:REINDEX CONCURRENTLY
- PostgreSQL12版本之后:減少了在創建GiST,GIN,SP-GiST索引的WAL日志量
- PostgreSQL 12 只能配置一個:recovery_target, recovery_target_lsn, recovery_target_name, recovery_target_time, recovery_target_xid.
- pg_basebackup從PostgreSQL 10之后可以支持限流
6. PostgreSQL 13版本的新特性
6.1 新特性總結
總結如下:
- 對vacumm增加了並行的功能
- 改變流復制的配置可以不用重啟數據庫了
- 更多的一些情況下可以對分區進行裁剪和智能join
- 如原先智能join必須兩個分區的范圍精確相同,現在可以更智能了。CAFjFpRdjQvaUEV5DJX3TW6pU5eq54NCkadtxHX2JiJG_GvbrCA@mail.gmail.com"">https://www.postgresql.org/message-id/CAFjFpRdjQvaUEV5DJX3TW6pU5eq54NCkadtxHX2JiJG_GvbrCA@mail.gmail.com
- 三個表的full outer join也可以走wise join
- 分區智能join是從PostgreSQL 11版本添加的功能
- 分區表可以支持before trigger(不允許改變插入數據的目標分區)
- 分區表可以支持邏輯復制了
- 之前只能把分區表的各個分區單獨的做為復制源,現在可以把分區表直接做為復制源。
- 先前訂閱者只能把數據同步到非分區表,現在可以把數據同步到分區表
- Allow whole-row variables (that is, table.*) to be used in partitioning expressions (Amit Langote)
- 支持異構分區表邏輯復制: http://www.postgres.cn/v2/news/viewone/1/604
- https://www.postgresql.org/message-id/flat/CA+HiwqH=Y85vRK3mOdjEkqFK+E=ST=eQiHdpj43L=_eJMOOznQ%40mail.gmail.com
- 索引中重復的項做了優化處理,更節省空間。重復的項只存儲一次
- 聚合時使用hash算法可以使用磁盤做溢出存儲
- 增量排序(Incremental sort)的功能
- 提升了PL/pgSQL中簡單表達式的性能
- pg_stat_statements插件增加了選項可以跟蹤SQL的planning time,而不僅僅是執行時間
6.2 分區表智能join
6.2.1 不要求分區的范圍完全相等
具體可見:advanced partition matching algorithm for partition-wise join
看例子:
create table t1(id int) partition by range(id);
create table t1_p1 partition of t1 for values from (0) to (100);
create table t1_p2 partition of t1 for values from (150) to (200);
create table t2(id int) partition by range(id);
create table t2_p1 partition of t2 for values from (0) to (50);
create table t2_p2 partition of t2 for values from (100) to (175);
然后我們分別在PostgreSQL 12版本和PostgreSQL 13執行下面的SQL:
explain select * from t1, t2 where t1.id=t2.id;
對比如下:
6.2.2 三個分區表full outer join也智能join
看例子:
create table p (a int) partition by list (a);
create table p1 partition of p for values in (1);
create table p2 partition of p for values in (2);
set enable_partitionwise_join to on;
6.3 索引消除重復項
PostgreSQL 13中對索引的重復的項做了優化處理,更節省空間。重復的項只存儲一次。
看例子:
PG13索引的大小:
postgres=# create table test01(id int, id2 int);
CREATE TABLE
postgres=# insert into test01 select seq, seq / 1000 from generate_series(1, 1000000) as seq;
INSERT 0 1000000
postgres=# create index idx_test01_id2 on test01(id2);
CREATE INDEX
postgres=# \timing
Timing is on.
postgres=# select pg_relation_size('idx_test01_id2');
pg_relation_size
------------------
7340032
(1 row)
如果是PG9.6:
postgres=# select pg_relation_size('idx_test01_id2');
pg_relation_size
------------------
22487040
(1 row)
可以看到索引的大小是以前的三分之一。
索引中去除重復項的原理:
- 類似倒排索引GIN,一個索引的key值,對應多個物理行。
- pg_upgrade升級數據庫后,需要reindex才能讓舊索引使用到此特性
有一些情況可能無法去除重復項:
- numeric不能使用去重
- jsonb類型不能使用去重
- float4和float8不能使用去重
- INCLUDE indexes不能使用去重
- text, varchar, and char 類型的索引使用了非確定性排序(nondeterministic collation)
- Container types (such as composite types, arrays, or range types) cannot use deduplication.
給索引增加了存儲參數deduplicate_items以支持這個功能。
6.4 聚合時使用hash算法可以使用磁盤做溢出存儲
以前當表特別大時,hash表超過work_mem的內存時,聚合時就走不到hash,只能走排序的算法,而排序聚合比hash聚合通常慢幾倍的性能,現在有了用磁盤存儲溢出的hash表,聚合的性能大大提高
同時增加了參數hash_mem_multiplier,hasn聚合的內存消耗現在變成了work_mem* hash_mem_multiplier,默認此參數hash_mem_multiplier為1,即hash表的大小還是以前的大小
現在使用了 HyperLogLog算法來估算唯一值的個數,減少了內存占用。
請看例子:
CREATE TABLE t_agg (x int, y int, z numeric);
INSERT INTO t_agg SELECT id % 2, id % 10000, random()
FROM generate_series(1, 10000000) AS id;
VACUUM ANALYZE;
SET max_parallel_workers_per_gather TO 0;
SET work_mem to '1MB';
explain analyze SELECT x, y, avg(z) FROM t_agg GROUP BY 1,2;
在12.4版本中聚合使用了排序算法,時間花了14.450秒,如下圖所示:
而在13版本中,走了hash聚合,時間花了6.186秒,時間縮短了一半還多,如下圖所示:
6.5 增量排序(Incremental sort)的功能
官方手冊中也有例子:https://www.postgresql.org/docs/13/using-explain.html#USING-EXPLAIN-BASICS
見我們的例子:
create table test01(n1 int, n2 int);
insert into test01 select seq/3, (seq / 97) % 100 from generate_series(1, 4000000) as seq;
create index idx_test01_n1 on test01(n1);
analyze test01;
然后分別在PostgreSQL 12版本和PostgreSQL 13版本下看下面SQL的執行計划和執行時間:
explain analyze select * from test01 order by n1, n2;
可以看到使用了增量排序后,速度更快了。在PG13中為1.447秒,在PG12中為2.015秒:
6.6 vacumm增加了並行的功能
具體實現是SQL命令vacuum上增加了parallel的選項:
vacuum (parallel 5);
命令行工具vacuumdb增加了選項—parallel=:
vacuumdb -P 3
主要是實現了對索引的並行vacuum
並行度受到max_parallel_maintenance_workers參數的控制
索引的大小至少要大於參數min_parallel_index_scan_size的值(512KB),才會並行vacuum
具體可以見:https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=40d964ec997f64227bc0ff5e058dc4a5770a70a9
6.7 其它的一些功能增強
增強的功能如下:
-
增加參數autovacuum_vacuum_insert_threshold、 autovacuum_vacuum_insert_scale_factor:
- 原先如果對於只有insert的表(append only table)不會觸發vacuum,這時會一直累積到aggressivevacuum,這樣會導致vacuum太不及時,現在有這個參數,解決了這個不及時的問題。
- 為了實現這個功能在pg_stat_all_tables表中增加了列n_ins_since_vacuum,記錄自上一次vacuum以來這個表插入了多少行。
- https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=b07642dbcd8d5de05f0ee1dbb72dd6760dd30436
- https://news.knowledia.com/US/en/articles/postgresql-v13-new-feature-tuning-autovacuum-on-insert-only-tables-f0a6f5028ecaed253723bab69926a04b45cd3a2f
-
reindexdb增加了—jobs,可以建多個數據庫連接來並發來重建索引。
- wal_skip_threshold
- Skip WAL for new relfilenodes, under wal_level=minimal.
- https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=c6b92041d38512a4176ed76ad06f713d2e6c01a8
- 提升了PL/pgSQL中簡單表達式的性能,如”x+1”或”x>0”,性能提升大致2倍
- effective_io_concurrency參數
- 默認值改為1,與原先一樣。如果設置大於1的值,則為實際的並發IO
- 測試發現PostgreSQL在bitmap index scan時,如果要讀入大量堆page,讀IO的速度會遠低於正常的順序讀,影響性能,這時可以把此值設置大。
- 允許的范圍是 1 到 1000,或 0 表示禁用異步 I/O 請求。當前這個設置僅影響位圖堆掃描
- jsonb @>
- https://www.postgresql.org/message-id/12237.1582833074%sss.pgh.pa.us
- Less-silly selectivity for JSONB matching operators
- https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=a80818605e5447b9b846590c3d3fab99060cb53e
- pg_stat_slru 查看slru的統計信息
- https://www.postgresql.org/message-id/flat/20200119143707.gyinppnigokesjok%40development
- https://www.postgresql.org/docs/13/monitoring-stats.html#MONITORING-PG-STAT-SLRU-VIEW
- 原文地址:http://www.pgsql.tech/article_101_10000102