二月 19, 2024
摘要:在本教程中,您将学习如何调整函数的并行安全性。
目录
介绍
规划器无法自动确定函数是否并行安全,但在某些情况下,如果处理大型数据集,并行模式可以显著提高性能。规划器会使用的工作进程数受参数 max_parallel_workers_per_gather 的限制,这些进程又来自由 max_worker_processes 指定建立的进程池,数目受参数 max_parallel_workers 限制,只要 max_worker_processes <= 服务器 CPU 核数,就可以通过以下公式确定以并行模式执行的最大并发查询数:
#Q_concurrent_par = max_worker_processes /max_parallel_workers_per_gather(整数除法)
什么时候对函数启用并行是安全的?
只要您的代码不执行以下操作,您就应该准备好启用并行:
- 写入数据库。
- 访问序列。
- 更改事务状态。
- 对参数设置进行持久化更改。
- 访问临时表。
- 使用游标。
- 定义预备语句。
示例
让我们开始设置一个小的测试用例:
CREATE TABLE test1 (id integer, str text);
INSERT INTO test1 (id, str)
SELECT i, 'xxx' FROM generate_series(1, 1000000) AS s(i);
创建了一个包含 1'000'000 行的简单表。此外,让我们再创建一个简单的函数:
CREATE OR REPLACE FUNCTION pair_div_4 (i int)
RETURNS boolean AS $$
BEGIN
IF i % 2 = 0 AND i % 4 = 0 THEN
RETURN TRUE;
END IF;
RETURN FALSE;
END;
$$ LANGUAGE plpgsql;
当您在 WHERE 子句中调用这个函数时,优化器会做什么?
EXPLAIN ANALYZE SELECT * from test1 WHERE pair_div_4 (id);
QUERY PLAN
----------------------------------------------------------------------------------------------------------------
Seq Scan on test1 (cost=0.00..262476.00 rows=333333 width=8) (actual time=0.207..787.020 rows=250000 loops=1)
Filter: pair_div_4(id)
Rows Removed by Filter: 750000
Planning time: 0.100 ms
Execution time: 792.776 ms
(5 rows)
要更改上面的函数的并行安全性,请执行以下操作:
ALTER FUNCTION pair_div_4(i int) PARALLEL SAFE;
规划器会检测到pair_div_4()
是并行安全的,并以并行模式来运行查询。再来看一下执行计划:
EXPLAIN ANALYZE SELECT * from test1 WHERE pair_div_4 (id);
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------
Gather (cost=1000.00..189750.48 rows=333333 width=8) (actual time=0.502..511.806 rows=250000 loops=1)
Workers Planned: 1
Workers Launched: 1
-> Parallel Seq Scan on test1 (cost=0.00..155417.18 rows=196078 width=8) (actual time=0.283..451.079 rows=125000 loops=2)
Filter: pair_div_4(id)
Rows Removed by Filter: 375000
Planning time: 2.412 ms
Execution time: 517.604 ms
(8 rows)
如 explain 的输出所示,Workers Launched 标签的值为 1,这意味着此查询使用了 1 个工作进程 来执行,而前面的 EXPLAIN 是在没有并行的情况下执行的。