关于数据库:十八般武艺玩转GaussDBDWS性能调优路径干预

45次阅读

共计 4704 个字符,预计需要花费 12 分钟才能阅读完成。

摘要:门路生成是表关联形式确定的次要阶段,本文介绍了几个影响门路生成的因素:cost_param, scan 形式,join 形式,stream 形式,并从原理上剖析如何干涉门路的生成。

一、cost 模型抉择

顾名思义,cost_param 是管制 cost 相干的一个参数。在理解 cost_param 之前,先回顾一下选择率的概念,GaussDB 优化器中的选择率是指,当一个表有一个过滤或关联条件时,通过该条件能被选中的行数占总行数的比例,是介于 0~1 之间的一个实数。选择率在优化器中是一个重要的概念,次要利用于行数和 distinct 值的估算,行数和 distinct 值是打算生成中的基本要素。

首先,咱们来看带有过滤条件的基表行数如何估算。如果一个表只有一个过滤条件,那么以选择率乘以表的行数,即可失去过滤完的行数;如果有多个过滤条件,那么就须要算出一个综合的选择率,如何计算?形式有二:一是通过多列统计信息间接计算,二是通过组合单列的选择率。那么组合的形式就由参数 cost_param 决定了,具体地,

举一个例子,TPC-H 1x 的 part 表,过滤条件是:p_brand = ‘Brand#45’ and p_container = ‘WRAP CASE’,查看不同 cost_param 下的过滤后行数。

(1)cost_param=0

(2)cost_param=2

从估算出的行数(E-rows)和理论的行数(A-rows)比照能够看出,cost_param= 0 的不相干模型适宜 part 表的 p_brand 和 p_container 列。

其次,Join 的行数怎么估算的呢?原理跟过滤条件的行数估算是相似的,如果没有多列统计信息能够应用,则也须要独自计算每个条件的选择率,而后计算出综合选择率,得出行数。例如 TPC-H 1x lineitem 和 orders 关联,关联条件是:l_orderkey = o_orderkey and o_custkey = l_suppkey,不同 cost_param 的执行状况如下:

(1)cost_param=0

(2)cost_param=2

此例中,Join 的列之间也适宜齐全相干模型,这与 l_orderkey 和 l_suppkey 的散布是吻合的。

因为 TPC- H 的模型靠近齐全不相干模型,因而 cost_param= 0 模型能够较好的形容场景,理论利用中,用户能够依据具体业务场景来调整模型,行数估算的准确性是打算生成的重要保障,在调优中查看估算的最间接的中央。GaussDB 会在后续版本中新增更多的模型供业务需要抉择。

二、Scan形式的抉择

GaussDB 中扫描形式次要分程序扫描和索引扫描,每种扫描形式都对应若干扫描算子,程序扫描在行列存中对应的扫描算子别离是 Seq Scan 和 CStore Scan 算子(上面咱们探讨中不加区分)。这些扫描算子大部分都能够通过开关来进行调控,例如 Seq Scan,如果设置 enable_seqscan=off,则示意不会优先选择 Seq Scan,而不是肯定不会选。扫描形式的抉择,很大水平上决定了获取基表数据的门路。咱们以如下的例子来阐明:

select l_orderkey, o_custkey from lineitem, orders where l_orderkey =
o_orderkey;

lineitem 散布键是 l_orderkey,并且在 l_orderkey 上有 index,orders 散布键是 o_orderkey。默认状况下,Scan 的形式如下:

两个表都是程序扫描的门路,关联形式抉择了 Hash Join。如果把 Seq Scan 关掉(enable_seqscan=off), 打算如下:

lineitem 的扫描变成了 Index Only Scan(因为 l_orderkey 的类型是 int),而在 orders 表上依然抉择 Seq Scan(因为没有其余门路),同时关联形式也变为了 Nest Loop,因为 Hash Join 须要全表扫描数据(lineitem 的 Seq Scan 曾经被关掉了)。优化器的抉择形式咱们从代价(E-costs)一栏中也能够看出。再把 Index Only Scan 关掉,看看打算如何变动:

扫描门路都变为了 Seq Scan,而且 Seq Scan 的代价都很大。此时既然都走了 Seq Scan,为什么不选 Hash Join 呢,把 Nest Loop 关掉,看看 Hash Join 打算的代价:

从代价上看出 Hash Join 的总代价比 Nest Loop 的小,但优化器没有抉择 Hash Join,这是因为优化器比拟门路代价时,会比拟 Startup 和 Total 代价,即启动代价和总代价,综合思考,E-costs 栏中显示的是总代价。把 explain_perf_mode 设置为 normal,查看原 Nest Loop 的启动代价:

红框中的两个 cost,别离是启动代价和总代价,在看 Hash Join 的 cost,显著 Hash Join 的启动代价比 Nest Loop 的大很多(启动代价代表了输入第一条数据的代价),优化器在比拟门路时,综合了这两个代价,最终举荐了 Nest Loop 的门路。

从下面的例子能够看出,扫描门路的调控,能够扭转门路生成,正当的搭配是生成最优打算的前提,默认状况下,GaussDB 优化器能够依据现有的门路抉择(如下面的 lineitem 有两条扫描门路,orders 只有一条扫描门路),最初确定出最优的一条。两条门路代价比拟时,总代价不是惟一因素,但总代价越小,个别也会越容易被选中。

三、关联形式的抉择

GaussDB 优化器中表关联的次要形式有:Nest Loop,Hash Join 和 Merge Join,别离能够通过 enable_nestloopenable_hashjoinenable_mergejoin 进行管制,这种管制也不是相对的,能够了解为是否优先选择。大部分场景下,三种门路的代价关系:Hash Join < Merge Join < Nest Loop。咱们以一个简略的关联示例阐明,store_returns 和 store_sales 是 TPC-DS 1x 中两个表,SQL 如下:

select count(*) from store_returns, store_sales where sr_customer_sk =
ss_customer_sk;

默认状况下,优化器举荐 Hash Join 门路,打算如下:

如果把 Hash Join 关掉,则优化器抉择了 Merge Join 门路:

如果再把 Merge Join 门路关掉,可能就会抉择 Nest Loop 门路。关联形式的管制开关个别用于调优或躲避问题,但具体是否可能起作用要看具体的语句,除了以后关联形式,还有没有其余形式。理论场景中,一个语句中关联的算子较多,个别很难用参数 enable_hashjoin 或 enable_nestloop 或 enable_mergejoin 来管制某两个表的 Join 形式,GaussDB 中更粗疏的语句级别的调优伎俩是 Plan Hint,感兴趣的读者能够参考产品手册。

四、Stream 形式的抉择

Stream 算子是 GaussDB 分布式执行的要害算子之一,次要起到网络传输的作用,概要介绍能够参考:GaussDB(DWS)性能调优系列实战篇一:十八般武艺之总体调优策略。Stream 算子由参数 enable_stream_operator 管制,如果关掉 Stream 算子,则可能导致生成不下推的打算,例如:

因为 lineitem 表关联的键 l_partkey 不是 lineitem 的散布键,须要增加 Stream 算子,但 Stream 性能被禁,于是只能生成不下推打算。

GaussDB 打算中常见的次要 Stream 算子包含 Redistribute、Broadcast 和 Gather。Gather 个别是分布式打算中,CN 用于收集 DN 的数据进行最初的解决,除非最初收集的行数十分多,这个算子波及性能问题个别较少。Redistribute 和 Broadcast 一是对“互补”的算子,前者用于重散布,后者用于播送,生成打算时,优化器会依据代价大小来抉择。当 Join Key 没有蕴含表的散布键的时候,个别会增加 Redistribute 门路,能抉择 Redistribute 门路实践上也可抉择 Broadcast 门路,最终抉择哪条门路要看优化器估算的代价是多少。这两个算子能够通过参数 enable_redistribute 和 enable_broadcast 进行管制。

在 SMP 开启的状况下,当并行度(dop)大于 1 时,个别还会有 Local Redistribute、Split Redistribute、Local Broadcast 和 Split Broadcast;当歪斜优化开启时,还有 PART REDISTRIBUTE PART ROUNDROBIN、PART_REDISTRIBUTE_PART_BROADCAST、PART_REDISTERIBUTE_PART_LOCAL 等等,这些也是 Stream 算子,次要就是重散布、播送、RoundRobin 的一些扩大模式,这里咱们不一一介绍了,感兴趣的读者能够参考 GaussDB DWS 产品手册。

咱们思考两个表的简略关联,store_sales 和 sr_tbl,它们的散布键别离是 ss_item_sk 和 sr_returned_date_sk,Join 条件是 store_sales.ss_customer_sk =sr_tbl. sr_customer_sk,执行后果如下:

因为两个表的散布键都不是 Join Key,因而走 Hash Join 门路的话须要有一个表做 Broadcast 或者两个表都做 Redistribute,然而 store_sales 表比拟大(E-rows 显示 28.7 亿行),而 sr_tbl 表行数估算比拟少(E-rows 显示 100 行),优化器认为适宜做 Broadcast。于是最终抉择了一边 Broadcast 的打算。

对于这个打算,因为 sr_tbl 表统计信息不精确(如果是两头后果集,则示意两头后果集估算不准),一种调优的办法是,将 sr_tbl 的表统计信息从新收集精确一些(如果 sr_tbl 是两头后果集,则无奈收集),另一种办法是让 sr_tbl 走 Redistribute 门路,而后者咱们又有两种形式来实现,一是用 Plan Hint,即在生成打算时,通知优化器走 Redistribute 门路,二是把 Broadcast 关掉。禁用 Broadcast 后,执行打算如下:

本列中,开启了 SMP 自适应,即优化器会依据系统资源和以后 Active SQL 数量来自行决定并行度(dop),如果 Redistribute 和 Broadcast 抉择不当,则可能导致

(1)Broadcast 打算会呈现下盘

(2)两个打算的并行度不一样,最终执行工夫可能会差别比拟大。

对于 Stream 形式的管制,个别的调优形式有 Plan Hint、GUC 参数、改善统计信息或估算信息。

五、结束语

本文介绍的 cost_param 属于 cost 底层参数,倡议对数据特色和应用场景比拟相熟的 DBA 谨慎应用。Scan、Join、Stream 调控的根本根据也是代价,代价个别体现在执行耗时上,调优时可从 Performance 中辨认出性能的瓶颈点,剖析抉择的算子是否与代价匹配。另外,除了本文介绍的 Session 级别的控制参数外,还有基表、两头后果的行数,也能够通过 Plan Hint 进行语句级别的调控,感兴趣读者可通过 GaussDB DWS 产品文档进一步理解。

本文分享自华为云社区《GaussDB(DWS)性能调优系列实战篇五:十八般武艺之门路干涉》,原文作者:- 大道至简 –。

点击关注,第一工夫理解华为云陈腐技术~

正文完
 0