实际并行workers数量不等于postgresql.conf中设置的max_parallel_workers_per_gather数量

这篇具有很好参考价值的文章主要介绍了实际并行workers数量不等于postgresql.conf中设置的max_parallel_workers_per_gather数量。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1 前言

  • 本文件的源码来自PostgreSQL 14.5,其它版本略有不同
  • 并行workers并不能显箸提升性能。个人不建议使用并行worker进程,大多数情况下采用postgresql.conf默认配置即可。

PostgreSQL的并行workers是由compute_parallel_worker函数决定的,compute_parallel_worker是估算扫描所需的并行工作线程数,并不是您在postgresql.conf中设置的max_parallel_workers_per_gather数量,compute_parallel_worker会根据heap_pages、index_pages、max_workers(max_parallel_workers_per_gather)来决定并行工作线程数量。

2 源码和调用位置

compute_parallel_worker共有4个地方调用

src\backend\optimizer\path\allpaths.c(801,21)
src\backend\optimizer\path\allpaths.c(3724,21)
src\backend\optimizer\path\costsize.c(707,33)
src\backend\optimizer\plan\planner.c(5953,21)

compute_parallel_worker的声明

src\include\optimizer\paths.h(59,12)

compute_parallel_worker的实现

src\backend\optimizer\path\allpaths.c(3750,1)

compute_parallel_worker的源码

/*
 * Compute the number of parallel workers that should be used to scan a
 * relation.  We compute the parallel workers based on the size of the heap to
 * be scanned and the size of the index to be scanned, then choose a minimum
 * of those.
 *
 * "heap_pages" is the number of pages from the table that we expect to scan, or
 * -1 if we don't expect to scan any.
 *
 * "index_pages" is the number of pages from the index that we expect to scan, or
 * -1 if we don't expect to scan any.
 *
 * "max_workers" is caller's limit on the number of workers.  This typically
 * comes from a GUC.
 * "max_workers"就是postgresql.conf中max_parallel_workers_per_gather的值
 */
int
compute_parallel_worker(RelOptInfo *rel, double heap_pages, double index_pages,
						int max_workers)
{
	int			parallel_workers = 0;

	/*
	 * If the user has set the parallel_workers reloption, use that; otherwise
	 * select a default number of workers.
     * 不需要优化,直接来自表级存储参数parallel_workers
     * 详见第3节直接使用postgresql.conf中设置的max_parallel_workers_per_gather数量
	 */
	if (rel->rel_parallel_workers != -1)
		parallel_workers = rel->rel_parallel_workers;
	else
	{
		/*
		 * If the number of pages being scanned is insufficient to justify a
		 * parallel scan, just return zero ... unless it's an inheritance
		 * child. In that case, we want to generate a parallel path here
		 * anyway.  It might not be worthwhile just for this relation, but
		 * when combined with all of its inheritance siblings it may well pay
		 * off.
		 */
		if (rel->reloptkind == RELOPT_BASEREL &&
			((heap_pages >= 0 && heap_pages < min_parallel_table_scan_size) ||
			 (index_pages >= 0 && index_pages < min_parallel_index_scan_size)))
			return 0;

		if (heap_pages >= 0)
		{
			int			heap_parallel_threshold;
			int			heap_parallel_workers = 1;

			/*
			 * Select the number of workers based on the log of the size of
			 * the relation.  This probably needs to be a good deal more
			 * sophisticated, but we need something here for now.  Note that
			 * the upper limit of the min_parallel_table_scan_size GUC is
			 * chosen to prevent overflow here.
			 */
			heap_parallel_threshold = Max(min_parallel_table_scan_size, 1);
			while (heap_pages >= (BlockNumber) (heap_parallel_threshold * 3))
			{
				heap_parallel_workers++;
				heap_parallel_threshold *= 3;
				if (heap_parallel_threshold > INT_MAX / 3)
					break;		/* avoid overflow */
			}

			parallel_workers = heap_parallel_workers;
		}

		if (index_pages >= 0)
		{
			int			index_parallel_workers = 1;
			int			index_parallel_threshold;

			/* same calculation as for heap_pages above */
			index_parallel_threshold = Max(min_parallel_index_scan_size, 1);
			while (index_pages >= (BlockNumber) (index_parallel_threshold * 3))
			{
				index_parallel_workers++;
				index_parallel_threshold *= 3;
				if (index_parallel_threshold > INT_MAX / 3)
					break;		/* avoid overflow */
			}

			if (parallel_workers > 0)
				parallel_workers = Min(parallel_workers, index_parallel_workers);
			else
				parallel_workers = index_parallel_workers;
		}
	}

	/* In no case use more than caller supplied maximum number of workers */
	parallel_workers = Min(parallel_workers, max_workers);

	return parallel_workers;
}

3 直接使用postgresql.conf中设置的max_parallel_workers_per_gather数量

如果要使用指定数量的并行worker数,必须使用存储参数parallel_workers。

alter table tab set (parallel_workers=8);

配置了存储参数后,compute_parallel_worker就不在对并行worker数优化,直接返回配置的parallel_workers数量。

if (rel->rel_parallel_workers != -1)
		parallel_workers = rel->rel_parallel_workers;
  • 注意:如果不设置表级存储参数parallel_workers,实际的并行工作线程数由compute_parallel_worker根据heap_pages、index_pages、max_workers来决定并行工作线程数量,因此会出现实际并行工作数量不等于postgresql.conf中设置的max_parallel_workers_per_gather的情况。
    实际并行workers数量不等于postgresql.conf中设置的max_parallel_workers_per_gather数量,postgresql,PostgreSQL
    实际并行workers数量不等于postgresql.conf中设置的max_parallel_workers_per_gather数量,postgresql,PostgreSQL

  • 在次强制:并行workers并不能显箸提升性能。个人不建议使用并行worker进程,大多数情况下采用postgresql.conf默认配置即可。文章来源地址https://www.toymoban.com/news/detail-690778.html

到了这里,关于实际并行workers数量不等于postgresql.conf中设置的max_parallel_workers_per_gather数量的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 2. postgresql并行扫描(1)——pg强制走并行扫描建表及参数配置

    转载自:https://developer.aliyun.com/article/700370 max_parallel_workers_per_gather 参数控制执行节点的最大并行进程数,通过以上并行计划可知,开启并行后,会启动两个 worker 进程(即 Workers Launched: 2)并行执行 https://developer.aliyun.com/article/684431 并行扫描的理念很朴素,即启动多个 worker

    2024年02月09日
    浏览(35)
  • PostgreSQL中如何配置Huge page的数量

    在了解如在PG中如何配置大页之前,我们先要对大页进行一定的了解,为什么要配置大页,配置大页的好处有哪些。 我们日常的操作系统中,程序不直接使用内存,而是使用虚拟内存地址来处理内存分配,避免计算的复杂性和物理地址映射到应用程序内存空间的复杂性。虚拟

    2024年02月15日
    浏览(27)
  • 如何在C/C++中测量一个函数或者功能的运行时间(串行和并行,以及三种方法的实际情况对比)

    本文算是一个比较完整的关于在 C/C++ 中测量一个函数或者功能的总结,最后会演示三种方法的对比。 最常用的测量方法是使用 clock() 来记录两个 CPU 时间点 clock_t ,然后做差。这个方法的好处在于非常简单易写,如下(第一行是为说明需要导入哪个库): 需要注意 3 点:

    2024年04月23日
    浏览(40)
  • NIFI分页获取Postgresql数据到Hbase中_实际操作---大数据之Nifi工作笔记0049

    首先看一下整体流程,可以看到这里用的PutHbaseJson处理器,把数据导入到 hbase中的 注意这里也可以使用PutSql导入数据,通过phoenix的jdbc驱动,然后把数据利用PutSql处理器导入到 Hbase中,但是我这里的时候报错了,然后一直没解决,所以最后用了PutHbaseJson处理器,把数据存入到Hbase中去.  

    2024年02月06日
    浏览(45)
  • 链表逆置的两种方法

    原链表图:   方法一:头插法链表 逆置 1.断开头节点与其他节点的连接(提前存好head-next的地址)     Node* p = head-next;     Node* q = p-next;     head-next = NULL; 2. 头插法 在head后面插入p后链表的各个节点     p-next = head-next;     head-next = p; p、q指针往后移     p = q;     if

    2024年02月16日
    浏览(47)
  • CUDA:矩阵转置的GPU实现(Share Memory)

    本文参加2022CUDA on Platform线上训练营学习笔记 欢迎各位 大犇 提意见 上图中将 m * n 的矩阵A通过矩阵转置变成了 n * m 的 A T ,简单来讲矩阵转置即为将原始矩阵的第一行转置为目标矩阵的第一列,以此类推, 相信基础扎实的你简单地看看CPU端的代码就能理解 定义一个名为 cpu_t

    2024年02月12日
    浏览(36)
  • js 校验 大于等于0小于等于100

    如果你想要在JavaScript中校验一个数值是否在0到100之间(包括0和100),你可以使用以下的函数: 你可以使用这个函数来检查一个值是否在指定的范围内。例如: 如果你需要在一个表单验证中使用这个函数,你可以这样做: 在这个例子中, validateRange 函数会检查用户输入的值

    2024年01月17日
    浏览(61)
  • MyBatis XML 中大于等于小于等于的写法

    第一种方法 :  XML转义字符 用了转义字符把 和 替换掉,然后就没有问题了 大于:gt; 小于:lt; 大于等于:gt;= 小于等于:lt;= 第二种方法 : ![CDATA[ sql语句 ]]语法 因为这个是xml格式的,所以不允许出现类似“”这样的字符,但是都可以使用![CDATA[ ]]符号进行说明,将此类符号

    2024年02月17日
    浏览(43)
  • mybatis中大于 ,小于 ,大于等于,小于等于 的转义字符

    实际的开发中,经常会遇到一些场景,比如 查询小于某个时间,或者是查询小于某个年龄 等。这个时候就需要在  MyBatis  的  XML  文件中使用一些  、=  等符号,但是如果直接使用的话文件会报错。可以通过下面的特殊符号转义。  注意:这是mybaits中支持的,不是sql中支

    2024年02月12日
    浏览(42)
  • Pytorch DataLoader中的num_workers (选择最合适的num_workers值)

    num_workers是Dataloader的概念,默认值是0。是告诉DataLoader实例要使用多少个子进程进行数据加载(和CPU有关,和GPU无关) 如果num_worker设为0,意味着每一轮迭代时,dataloader不再有自主加载数据到RAM这一步骤(因为没有worker了),而是在RAM中找batch,找不到时再加载相应的batch。缺点

    2024年02月02日
    浏览(69)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包