这是我参与「第四届青训营 」笔记创作活动的第1天
什么是 Cardinality?
在数据库中如果我们选择 CBO(Cost-based Optimizer) 作为查询优化器,那么一条SQL语句的执行就会有多种执行路径,CBO会用一个模型估算执行计划的代价,选择代价最小的执行计划。CBO 在做访问路径估算的时候有一个很重要的参数作为我们计算 Cost 的因数,这个就是我们在SQL的查询计划中通常所说的Cardinality(基数) ,即算子需要处理的行数。
一般公式如下:
Cardinality=MAX(Cardinality Factor * Rowcount,1)
浅述Spark 系统中 Join Cardinality 的估算方式
以 Apache Spark 2.2 中的 CBO 为例,它是一个先进的基于成本的优化框架,该框架收集并利用各种每列数据统计信息(例如,cardinality, number of distinct values, NULL values, max/min, average/max length等)来提高查询执行计划的质量。利用这些统计信息可帮助 Spark 在选择最佳查询计划时做出更好的决策。
在计算双向连接输出的基数之前,我们已知拥有其两个子节点的输出基数。同时,每个连接侧的基数不大于原始连接表中的记录数; 相反,它是在此连接运算符之前应用所有执行运算符后的符合条件记录的数目。现在,我们先计算内连接操作的基数,用它推导其他连接类型的基数。基数的计算公式为:
A join B on A.k = B.k
num(A IJ B) = num(A)*num(B)/max(distinct(A.k),distinct(B.k))
其中 num(A) 是在连接操作之前的表 A 中符合条件记录的数目,distinct 是联接列 k 的非重复值数。
通过计算内连接的基数,我们可以类似地推导出其他连接类型的连接基数,如下所示:
- 左外连接: 表示内连接输出基数与左连接外侧 A 的基数之间的较大值。这是因为我们仍然需要考虑外部的每条记录,尽管其中一些记录不会产生连接输出记录。
num(A LOJ B) = max(num(A IJ B),num(A)) - 右外连接:
num(A ROJ B) = max(num(A IJ B),num(B)) - 全外连接:
num(A FOJ B) = num(A LOJ B) + num(A ROJ B) - num(A IJ B)
思考和总结
初学SQL知识,期待各位大佬的指导。