OceanBase 并行执行参数 parallel_servers_target 理解

2024-06-14 05:44

本文主要是介绍OceanBase 并行执行参数 parallel_servers_target 理解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

为了最大程度降低 PX 使用难度,OceanBase 3.1 版起,parallel_max_servers 参数废弃。
用户只需用好 parallel_servers_target 即可。

target 的用途

用一个酒吧的例子来粗略理解下 parallel_servers_target 的意思:

target 先生开了一个酒吧。来这个酒吧里喝酒的都是一群一群的人。酒吧最多容纳100个人 (parallel_servers_target = 100)。

如果酒吧里面一个人都没有(比如刚刚开门),那么来的第一群人总是让他们进去,并且:

  • 如果他们的人数多于100人,则放100人进去。
  • 如果小于100人,例如 30 个人( /*+ parallel(30) */),则有多少放进去多少。

如果酒吧里已经有人在喝酒了,那么新来的一群人,target 会数一数:

  • 如果进去后酒吧装不下,则不让他们进去。
  • 反之,只要装得下,就放进去。

通过这种方式,target 先生可以保证:

  1. 酒吧不会空闲:即使来的每一群人都超过100人,他也有生意做。
  2. 酒吧不会太挤:他的策略可以保证酒吧里的人总是不会超过100人。

真实线程数计算

最简单的 select 场景

select /*+ parallel(30) */ * from t1;

假设 parallel_servers_target = 100, /*+ parallel(30) */,那么会启动 30 个线程来执行 SQL。

多个 dfo 的复杂场景

select /*+ parallel(30) / count() from t1, t2 group by t1.c1, t2.c1;

假设 parallel_servers_target = 100, /*+ parallel(30) */,那么一般来说会启动 60 个线程来执行 SQL。下面的 dfo 使用 30 个线程,上面的 dfo 使用 30 个线程,他们之间形成 producer-consumer 关系。

target 相对较小的场景

select /*+ parallel(30) */ * from t1;

假设 parallel_servers_target = 10, /*+ parallel(30) */,那么会启动 10 个线程来执行 SQL,而不是启动 30 个线程来执行 SQL!

复杂 SQL里,假设 parallel_servers_target = 10, /*+ parallel(30) */,那么会启动 10 个线程来执行 SQL,并且下面的 dfo 使用 5 个线程,上面的 dfo 使用 5 个线程(并不是每个 dfo 使用 10 个线程,没那么多资源)

更特殊的场景

  1. 某些计划形态,会同时调度 3 个 dfo 起来,假设 parallel_servers_target = 12, /*+ parallel(30) */,那么 dfo1 使用 4 个线程,dfo2 使用 4 个线程,dfo3 使用 4 个线程。
  2. 某些 dfo 只能用一个线程执行(计划上会有 local 标记,如2阶段聚集计算的第二阶段),线程的分配就更复杂了

复杂例子

update /*+ parallel(10) enable_parallel_dml */ lyqtest1 t1 set t1.num = (select num from lyqtest t2 where t2.num=3) + t1.num where pk_id < (select max(num) from lyqtest1) +1000========================================================================================================
|ID|OPERATOR                                              |NAME                        |EST. ROWS|COST |
--------------------------------------------------------------------------------------------------------
|0 |PX COORDINATOR                                        |                            |999      |38008|
|1 | EXCHANGE OUT DISTR                                   |:EX10004                    |999      |31276|
|2 |  INDEX INSERT                                        |LYQTEST1(INDEX_LYQ1)        |999      |30603|
|3 |   EXCHANGE IN DISTR                                  |                            |999      |30465|
|4 |    EXCHANGE OUT DISTR (PKEY HASH)                    |:EX10003                    |999      |29792|
|5 |     MATERIAL                                         |                            |999      |29119|
|6 |      INDEX DELETE                                    |LYQTEST1(INDEX_LYQ1)        |999      |28577|
|7 |       EXCHANGE IN DISTR                              |                            |999      |28439|
|8 |        EXCHANGE OUT DISTR (PKEY HASH)                |:EX10002                    |999      |27766|
|9 |         MATERIAL                                     |                            |999      |27093|
|10|          UPDATE                                      |                            |999      |26551|
|11|           EXCHANGE IN DISTR                          |                            |999      |26413|
|12|            EXCHANGE OUT DISTR (PKEY HASH)            |:EX10001                    |999      |25740|
|13|             MATERIAL                                 |                            |999      |19008|
|14|              SUBPLAN FILTER                          |                            |999      |13593|
|15|               MATERIAL                               |                            |999      |13451|
|16|                PX COORDINATOR                        |                            |999      |8035 |
|17|                 EXCHANGE OUT DISTR                   |:EX20002                    |999      |1303 |
|18|                  MATERIAL                            |                            |999      |630  |
|19|                   NESTED-LOOP JOIN                   |                            |999      |88   |
|20|                    EXCHANGE IN DISTR                 |                            |1        |16   |
|21|                     EXCHANGE OUT DISTR (BC2HOST)     |:EX20001                    |1        |15   |
|22|                      SUBPLAN SCAN                    |VIEW1                       |1        |13   |
|23|                       SCALAR GROUP BY                |                            |1        |13   |
|24|                        SUBPLAN SCAN                  |VIEW2                       |1        |13   |
|25|                         LIMIT                        |                            |1        |13   |
|26|                          EXCHANGE IN MERGE SORT DISTR|                            |1        |13   |
|27|                           EXCHANGE OUT DISTR         |:EX20000                    |1        |12   |
|28|                            LIMIT                     |                            |1        |12   |
|29|                             PX PARTITION ITERATOR    |                            |1        |11   |
|30|                              TABLE SCAN              |LYQTEST1(INDEX_LYQ1,Reverse)|1        |11   |
|31|                    PX PARTITION ITERATOR             |                            |999      |93   |
|32|                     TABLE SCAN                       |T1                          |999      |79   |
|33|               EXCHANGE IN DISTR                      |                            |1        |5    |
|34|                EXCHANGE OUT DISTR                    |:EX10000                    |1        |4    |
|35|                 PX BLOCK ITERATOR                    |                            |1        |4    |
|36|                  TABLE SCAN                          |T2                          |1        |4    |
========================================================================================================Outputs & filters: 
-------------------------------------0 - output(nil), filter(nil)1 - output(nil), filter(nil), dop=102 - output(nil), filter(nil), columns([{LYQTEST1: ({INDEX_LYQ1: (T1.NUM, T1.PK_ID, T1.__pk_increment)})}]), partitions(p[0-2]), conv_exprs([column_conv(NUMBER,PS:(38,0),NOT NULL,? + T1.NUM)], [T1.PK_ID], [T1.__pk_increment])3 - output([T1.NUM], [T1.PK_ID], [T1.__pk_increment], [column_conv(NUMBER,PS:(38,0),NOT NULL,? + T1.NUM)], [PARTITION_ID]), filter(nil)4 - (#keys=1, [column_conv(NUMBER,PS:(38,0),NOT NULL,? + T1.NUM)]), output([T1.NUM], [T1.PK_ID], [T1.__pk_increment], [column_conv(NUMBER,PS:(38,0),NOT NULL,? + T1.NUM)], [PARTITION_ID]), filter(nil), dop=105 - output([T1.NUM], [T1.PK_ID], [T1.__pk_increment], [column_conv(NUMBER,PS:(38,0),NOT NULL,? + T1.NUM)]), filter(nil)6 - output([T1.NUM], [T1.PK_ID], [T1.__pk_increment], [column_conv(NUMBER,PS:(38,0),NOT NULL,? + T1.NUM)]), filter(nil), table_columns([{LYQTEST1: ({INDEX_LYQ1: (T1.NUM, T1.PK_ID, T1.__pk_increment)})}])7 - output([T1.NUM], [T1.PK_ID], [T1.__pk_increment], [column_conv(NUMBER,PS:(38,0),NOT NULL,? + T1.NUM)], [PARTITION_ID]), filter(nil)8 - (#keys=1, [T1.NUM]), output([T1.NUM], [T1.PK_ID], [T1.__pk_increment], [column_conv(NUMBER,PS:(38,0),NOT NULL,? + T1.NUM)], [PARTITION_ID]), filter(nil), dop=109 - output([T1.NUM], [T1.PK_ID], [T1.__pk_increment], [column_conv(NUMBER,PS:(38,0),NOT NULL,? + T1.NUM)]), filter(nil)10 - output([T1.NUM], [T1.PK_ID], [T1.__pk_increment], [column_conv(NUMBER,PS:(38,0),NOT NULL,? + T1.NUM)]), filter(nil), table_columns([{LYQTEST1: ({LYQTEST1: (T1.PK_ID, T1.__pk_increment, T1.NUM, T1.NAME, T1.MONEY)})}]),update([T1.NUM=column_conv(NUMBER,PS:(38,0),NOT NULL,? + T1.NUM)])11 - output([T1.PK_ID], [T1.__pk_increment], [T1.NUM], [T1.NAME], [T1.MONEY], [column_conv(NUMBER,PS:(38,0),NOT NULL,? + T1.NUM)], [PARTITION_ID]), filter(nil)12 - (#keys=1, [T1.PK_ID]), output([T1.NUM], [T1.PK_ID], [T1.__pk_increment], [column_conv(NUMBER,PS:(38,0),NOT NULL,? + T1.NUM)], [T1.NAME], [T1.MONEY], [PARTITION_ID]), filter(nil), is_single, dop=113 - output([T1.NUM], [T1.PK_ID], [T1.__pk_increment], [column_conv(NUMBER,PS:(38,0),NOT NULL,? + T1.NUM)], [T1.NAME], [T1.MONEY]), filter(nil)14 - output([T1.NUM], [T1.PK_ID], [T1.__pk_increment], [?], [T1.NAME], [T1.MONEY]), filter(nil), exec_params_(nil), onetime_exprs_([subquery(1)]), init_plan_idxs_(nil)15 - output([T1.NUM], [T1.PK_ID], [T1.__pk_increment], [T1.NAME], [T1.MONEY]), filter(nil)16 - output([T1.NUM], [T1.PK_ID], [T1.__pk_increment], [T1.NAME], [T1.MONEY]), filter(nil)17 - output([T1.NUM], [T1.PK_ID], [T1.__pk_increment], [T1.NAME], [T1.MONEY]), filter(nil), dop=1018 - output([T1.NUM], [T1.PK_ID], [T1.__pk_increment], [T1.NAME], [T1.MONEY]), filter(nil)19 - output([T1.NUM], [T1.PK_ID], [T1.__pk_increment], [T1.NAME], [T1.MONEY]), filter(nil), conds(nil), nl_params_([VIEW1.MAX(NUM) + 1000])20 - output([VIEW1.MAX(NUM)]), filter(nil)21 - output([VIEW1.MAX(NUM)]), filter(nil), is_single, dop=122 - output([VIEW1.MAX(NUM)]), filter(nil), access([VIEW1.MAX(NUM)])23 - output([T_FUN_MAX(VIEW2.NUM)]), filter(nil), group(nil), agg_func([T_FUN_MAX(VIEW2.NUM)])24 - output([VIEW2.NUM]), filter(nil), access([VIEW2.NUM])25 - output([LYQTEST1.NUM]), filter(nil), limit(1), offset(nil)26 - output([LYQTEST1.NUM]), filter(nil), sort_keys([LYQTEST1.NUM, DESC])27 - output([LYQTEST1.NUM]), filter(nil), dop=1028 - output([LYQTEST1.NUM]), filter(nil), limit(1), offset(nil)29 - output([LYQTEST1.NUM]), filter(nil)30 - output([LYQTEST1.NUM]), filter(nil), access([LYQTEST1.NUM]), partitions(p[0-2]), limit(1), offset(nil)31 - output([T1.PK_ID], [T1.NUM], [T1.__pk_increment], [T1.NAME], [T1.MONEY]), filter(nil)32 - output([T1.PK_ID], [T1.NUM], [T1.__pk_increment], [T1.NAME], [T1.MONEY]), filter(nil), access([T1.PK_ID], [T1.NUM], [T1.__pk_increment], [T1.NAME], [T1.MONEY]), partitions(p[0-2])33 - output([T2.NUM]), filter(nil)34 - output([T2.NUM]), filter(nil), dop=1035 - output([T2.NUM]), filter(nil)36 - output([T2.NUM]), filter([T2.NUM = 3]), access([T2.NUM]), partitions(p0)

在这里插入图片描述
在这里插入图片描述

这篇关于OceanBase 并行执行参数 parallel_servers_target 理解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1059542

相关文章

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

Andrej Karpathy最新采访:认知核心模型10亿参数就够了,AI会打破教育不公的僵局

夕小瑶科技说 原创  作者 | 海野 AI圈子的红人,AI大神Andrej Karpathy,曾是OpenAI联合创始人之一,特斯拉AI总监。上一次的动态是官宣创办一家名为 Eureka Labs 的人工智能+教育公司 ,宣布将长期致力于AI原生教育。 近日,Andrej Karpathy接受了No Priors(投资博客)的采访,与硅谷知名投资人 Sara Guo 和 Elad G

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

如何在页面调用utility bar并传递参数至lwc组件

1.在app的utility item中添加lwc组件: 2.调用utility bar api的方式有两种: 方法一,通过lwc调用: import {LightningElement,api ,wire } from 'lwc';import { publish, MessageContext } from 'lightning/messageService';import Ca

4B参数秒杀GPT-3.5:MiniCPM 3.0惊艳登场!

​ 面壁智能 在 AI 的世界里,总有那么几个时刻让人惊叹不已。面壁智能推出的 MiniCPM 3.0,这个仅有4B参数的"小钢炮",正在以惊人的实力挑战着 GPT-3.5 这个曾经的AI巨人。 MiniCPM 3.0 MiniCPM 3.0 MiniCPM 3.0 目前的主要功能有: 长上下文功能:原生支持 32k 上下文长度,性能完美。我们引入了

【生成模型系列(初级)】嵌入(Embedding)方程——自然语言处理的数学灵魂【通俗理解】

【通俗理解】嵌入(Embedding)方程——自然语言处理的数学灵魂 关键词提炼 #嵌入方程 #自然语言处理 #词向量 #机器学习 #神经网络 #向量空间模型 #Siri #Google翻译 #AlexNet 第一节:嵌入方程的类比与核心概念【尽可能通俗】 嵌入方程可以被看作是自然语言处理中的“翻译机”,它将文本中的单词或短语转换成计算机能够理解的数学形式,即向量。 正如翻译机将一种语言

【C++高阶】C++类型转换全攻略:深入理解并高效应用

📝个人主页🌹:Eternity._ ⏩收录专栏⏪:C++ “ 登神长阶 ” 🤡往期回顾🤡:C++ 智能指针 🌹🌹期待您的关注 🌹🌹 ❀C++的类型转换 📒1. C语言中的类型转换📚2. C++强制类型转换⛰️static_cast🌞reinterpret_cast⭐const_cast🍁dynamic_cast 📜3. C++强制类型转换的原因📝

深入理解RxJava:响应式编程的现代方式

在当今的软件开发世界中,异步编程和事件驱动的架构变得越来越重要。RxJava,作为响应式编程(Reactive Programming)的一个流行库,为Java和Android开发者提供了一种强大的方式来处理异步任务和事件流。本文将深入探讨RxJava的核心概念、优势以及如何在实际项目中应用它。 文章目录 💯 什么是RxJava?💯 响应式编程的优势💯 RxJava的核心概念

如何通俗理解注意力机制?

1、注意力机制(Attention Mechanism)是机器学习和深度学习中一种模拟人类注意力的方法,用于提高模型在处理大量信息时的效率和效果。通俗地理解,它就像是在一堆信息中找到最重要的部分,把注意力集中在这些关键点上,从而更好地完成任务。以下是几个简单的比喻来帮助理解注意力机制: 2、寻找重点:想象一下,你在阅读一篇文章的时候,有些段落特别重要,你会特别注意这些段落,反复阅读,而对其他部分

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出 在数字化时代,文本到语音(Text-to-Speech, TTS)技术已成为人机交互的关键桥梁,无论是为视障人士提供辅助阅读,还是为智能助手注入声音的灵魂,TTS 技术都扮演着至关重要的角色。从最初的拼接式方法到参数化技术,再到现今的深度学习解决方案,TTS 技术经历了一段长足的进步。这篇文章将带您穿越时