跳转到主要内容
工程的博客

基于成本的优化器在Apache 2.2火花

分享这篇文章

这是砖之间联合工程工作的Apache火花工程团队(Sameer Agarwal Wenchen扇)和华为的工程团队(Ron胡锦涛和振华王)

Apache 2.2火花最近附带一个现有的基于成本的优化框架,收集和利用各种各样的每列的数据统计(如基数,不同值的数量,NULL值,最大值/最小值,平均/最大长度,等等)来提高查询执行计划的质量。利用这些数据有助于引发做出更好的决策,选择最优的查询计划。这些优化的例子包括选择正确的构建方面的散列连接,选择正确的连接类型(广播的散列连接比慢吞吞的散列连接)或调整多路连接顺序,等等。

在这个博客中,我们将深入了解火花的基于成本的优化器(CBO)和讨论引发收集和存储这些数据,如何优化查询,并显示其性能影响TPC-DS基准查询。

一个激励的例子

在其核心,火花的催化剂优化器为代表的查询计划是一个通用库树和顺序应用数量的优化规则来操纵它们。大多数这些优化基于启发式规则,即。,they only account for a query’s structure and ignore the properties of the data being processed, which severely limits their applicability. Let us demonstrate this with a simple example. Consider a query shown below that filters a tablet1大小为500 gb,加入与另一个表的输出t2大小为20 gb。火花实现这个查询使用一个散列连接,选择较小的连接关系的构建方(建立哈希表)和更大的关系的调查方1。考虑到t2小于t1,Apache 2.1火花会选择右边的构建方面的影响没有考虑过滤操作符(在这种情况下过滤掉大部分的t1的记录)。选择错误的一边的构建方经常迫使系统快速放弃一个散列连接,将分类合并加入由于内存限制。

Apache 2.2火花,另一方面,收集统计数据为每个操作符和数字,左边会过滤后只有100 mb(100万条记录),右边是20 gb(1亿条记录)。使用正确的大小/双方基数信息,引发2.2会选择左边构建查询导致显著的加速效果。

为了提高查询执行计划的质量,我们提高了火花SQL优化器与详细的统计信息。从详细的统计信息,我们统计数据传播到其他运营商向上遍历查询树。一旦传播,我们可以估计输出记录的数量和输出大小为每个数据库运营商支持和优化一个高效的查询计划。

统计数据收集框架

分析表命令

CBO依靠详细统计数据来优化查询计划。收集这些数据,用户可以发出这些新的SQL命令下面描述:

分析表table_name计算统计

上面的SQL语句可以收集表级统计信息如表的行数和字节数。请注意,分析,计算,统计数据保留关键字和可以采取特定的列名称作为参数,metastore存储所有的表级统计。

分析表table_name计算统计数据列column-name1 column-name2,…。

注意,它没有必要指定表的每一列分析的声明,只是那些用于过滤/联接条件,或者在集团条款等。

类型的数据

下面的表列出了详细的统计信息收集数字/日期/时间戳字符串/二进制数据类型分别。

鉴于CBO遍历引发的LogicalPlan后序的方式,我们可以传播这些统计数据自底向上到其他运营商。虽然有许多运营商我们可以估计他们的统计数据和相应的成本,在这里我们将描述这个过程估计统计数据的两个最复杂和有趣的运营商:过滤器加入

滤波器的选择性

过滤条件是一个谓词表达式的WHERE子句中指定SQL SELECT声明。可以复合谓词逻辑与逻辑表达式,,操作符组合多个单一的条件。通常有一个条件比较运算符=、> =2。因此,它可以相当复杂的选择性估计总体筛选器表达式。

让我们检查一些计算滤波器的选择性的复合逻辑表达式包括多个单一的逻辑表达式。

  • 逻辑表达式,其过滤的选择性是选择性左条件乘以选择性的条件,例如,fs (a和b) = f () * fs (b)
  • 逻辑或表达式,其滤波器的选择性是选择性条件,加上正确的选择条件,和-的选择性条件逻辑和正确的条件,
    也就是说,fs (a或b) = f (a) + fs (b) - fs (a和b) = f (a) + fs (b) - (fs (a) * fs (b))
  • 逻辑not表达式,其过滤因子是1.0 -原始表达式的选择性,也就是说,fs(不是)= 1.0 - fs (a)

接下来,让我们看看一个逻辑条件,可以有比较运算符,例如=,> =。为了推动直觉,我们将计算滤波器选择性平等(=)和小于(

  • 等于(=)条件:我们检查的文字常量值条件之间的落在合格范围内当前的最小和最大的列值。这是必要的,因为可能会改变先前由于条件适用范围。如果常量值超出合格范围,那么滤波器选择性是0.0。否则,它的逆不同值的数量(注意,没有额外的直方图信息,我们假设一个列值均匀分布)。未来版本将利用直方图来进一步提高估计精度。
  • 小于(这里我们检查的文字值恒定条件下降。如果是比当前最小列值小,那么滤波器选择性是0.0(如果是大于当前的极大值,然后选择性是1.0)。否则,我们计算基于可用的信息过滤因子。如果没有柱状图,我们按比例分配和设置过滤器选择性:(常数-最小值)/(最大值-最小值)。另一方面,如果有一个柱状图,我们可以计算滤波器选择性通过添加的密度直方图桶之间当前列最小值和常数的值。同时,注意不断在右边的条件将成为新的最大列值。

  • 加入基数

    既然我们已经讨论了滤波器的选择性,我们来谈谈加入输出基数。在计算基数的双向连接输出之前,我们应该已经有它的子节点的输出基数。每加入一方的基数不大于原始连接表的记录数;相反,它是合格的数量记录在应用所有的执行运营商在这之前连接操作符。这里我们特别感兴趣的计算基数内连接操作的,因为它常被用来推导其他连接类型的基数。我们计算的行数加入B。k = B.k为:

    num (A IJ) = num (A) * num (B) / max(不同的(a.k.),不同的(B.k))

    在num (A)合格的记录的数量吗表一个立即在连接操作,不同的是加入的不同值的数量列k。

    通过计算内连接的基数,我们同样可以推导出连接基数为其他连接类型如下:

    • 左外连接:num (LOJ B) = max (num (IJ B), num (A))意义更大的价值之间的内连接输出基数和基数的左边加入外端a。这是因为我们仍需要外部的因素在每个记录方面虽然有些不产生加入输出记录。
    • 右外连接:num (ROJ B) = max (num (IJ B), num (B))
    • 完全外连接:num (FOJ B) = num (LOJ B) + num (ROJ B) - num (IJ B)

    最优方案选择

    现在我们是带着中间数据统计,我们讨论如何引发SQL使用这些信息来选择最好的查询计划。早些时候我们解释选择构建基于精确的基数和统计数据散列连接操作。

    同样,与精确的基数和大小估计运营商前一个连接操作符,我们可以更好地估计加入的大小来决定是否一起能满足广播标准。

    这些统计数据也帮助我们利用基于成本加入重新排序优化。我们采用动态规划算法(1979年其密封)3选择最好的办法连接顺序。更具体地说,当建筑物没办法连接,我们只保留最好的计划(成本最低的)相同的物品。例如,对于我家的加入,我们只保留最好的连接计划项目的订单{A, B, C}在计划(连接B)加入C(连接C)加入B和(B和C)加入。我们认为所有的组合包括调整算法留下了很深的树,浓密的树木,right-deep-trees。我们也删除笛卡儿积的候选人在构建一个新的计划,如果不存在联接条件涉及引用来自左、右子树。这种修剪策略大大减少了搜索空间。

    大多数数据库优化器CPU和I / O的成本因素分别估计整个运营商成本。在火花,我们估计的成本连接操作符用一个简单的公式:

    成本=重量*基数+(1.0 -重量)*大小4

    加入成本公式的第一部分大致对应于CPU成本和第二部分大致对应于I / O开销。加入树的成本是所有中间连接的成本的总和。

    查询指标和分析

    我们花了一个非侵入性的方法,添加这些引发全球配置添加一个基于成本的优化spark.sql.cbo.enabled启用/禁用这个特性。在火花2.2中,这个参数设置为默认情况下。这是一个有意识的短期选择记住,火花用于生产成千上万的公司和改变默认的行为可能是不受欢迎的对现有生产工作负载。

    配置和方法论

    我们都跑TPC-DS基准查询与Apache 2.2火花4节点集群(华为FusionServer RH2288 40核心和384 GB内存)和比例因子为1000(即。,1 tb的数据)。我们花了~ 14分钟收集统计所有24表(425列)。

    在研究端到端结果之前,让我们先看一个特定TPC-DS查询(Q25;所示),以便更好地理解基于成本的加入顺序的影响。这个查询涉及到三个事实表:store_sales(29亿行),store_returns(2.88亿行)catalog_sales(14.4亿行)。它还包括三个维度表:date_dim(73 k行),存储(1 k行)和项目(300 k行)。

    <br/>选择i_item_id,i_item_desc,s_store_id,s_store_name,总和(ss_net_profit)作为store_sales_profit,总和(sr_net_loss)作为store_returns_loss,总和(cs_net_profit)作为catalog_sales_profitstore_sales、store_returns catalog_sales date_dim d1, d2 date_dim, date_dim d3,商店,项在哪里d1.d_moy=4d1.d_year=2001年d1.d_date_sk=ss_sold_date_ski_item_sk=ss_item_sks_store_sk=ss_store_skss_customer_sk=sr_customer_skss_item_sk=sr_item_skss_ticket_number=sr_ticket_numbersr_returned_date_sk=d2.d_date_skd2.d_moy之间的410d2.d_year=2001年sr_customer_sk=cs_bill_customer_sksr_item_sk=cs_item_skcs_sold_date_sk=d3.d_date_skd3.d_moy之间的410d3.d_year=2001年集团通过i_item_id、i_item_desc s_store_id s_store_name订单通过i_item_id、i_item_desc s_store_id s_store_name限制One hundred.

    Q25没有国会预算办公室

    让我们先看看实现加入树Q25没有国会预算办公室(如下所示)。这也是通常被称为一个留下了很深的树。在这里,加入# 1和# 2大fact-to-fact表连接,加入3事实表store_sales,store_returns,catalog_sales在一起,产生非常大的中间表。这两个连接执行与大洗牌加入加入# 1输出1.99亿行。总的来说,当国会预算办公室查询需要241秒禁用

    Q25与国会预算办公室

    与基于成本的优化,另一方面,激发创造了一个最优加入计划,减少了中间数据大小(如下所示)。在本例中,创建了一个火花浓密的树而不是留下了很深的树。CBO启用时,火花加入相应的事实表date_dim维度表第一(之前任何fact-to-fact连接)。避免大型fact-to-fact连接意味着避免大型昂贵的打乱。在这个查询中,这减少了中间数据大小大约也就是(相比以前的情况)。因此,Q25只花了71秒,代表的加速3.4倍

    TPC-DS查询性能

    现在我们已经建立了一个直觉的改进从何而来,让我们看看端到端TPC-DS查询结果。下图显示了所有TPC-DS查询和查询时间没有国会预算办公室:

    首先,请注意,大约一半的TPC-DS基准查询不显示性能的变化。这是因为没有改变在运行查询时查询计划有或没有国会预算办公室(即。,even without CBO, existing heuristics in Spark’s Catalyst optimizer were able to optimize these queries well). For the remaining queries, while there were improvements across the board, what’s perhaps more interesting is the set of 16 queries where CBO brought substantial changes to the query plan and improved performance by more than30%(如下所示)。总的来说,我们发现这些16个查询的几何平均加速约2.2 x Q72实现的最大加速8倍

    结论

    回顾一下,这篇文章强调了新的基于成本的优化器的各个方面在Apache 2.2火花。我们讨论了统计数据收集框架的细节,基数传播对过滤器和连接,它们支持的基于成本的优化(构建选择和多路连接重新排序),及其性能影响TPC-DS基准查询。

    在过去的一年里,我们已经解决了共有32子任务生成超过50 +补丁和7000 +行代码在CBO的保护伞之下JIRA火花- 16026。说,利用基于成本的优化在分布式数据库是一个极其复杂的问题,这仅仅是第一步在这个方向。在将来的版本中,我们计划继续从事这个方向通过添加更复杂的统计数据(直方图,count-min草图,分区级统计数据等)和炼油成本公式。

    我们兴奋的进展和改进。希望你能喜欢我们鼓励你尝试新的基于成本的优化器在Apache 2.2火花!

    阅读更多

    你可以查看我们的火花峰会2017说:2.2基于成本的优化器在火花


    1. 这里的理由是,较小的关系更可能适合在内存中。
    2. 代表“平等零安全”返回true,如果两个操作数是零,错误的如果一个操作数为空。
    3. p·格里菲思其密封,m . m . Astrahan d·d·Chamberlin r·a·洛里·t·g .价格“访问路径选择在关系数据库管理系统”,ACM SIGMOD研讨会论文集,1979
    4. 体重是一个调优参数,可以通过spark.sql.cbo.joinReorder.card配置。体重(0.7默认情况下)
    免费试着砖
    看到所有工程的博客的帖子