sql 循环处理数据_图文介绍 SQL 的三种查询计划处理模型,Spark 用了其中两个

我已经在之前的 《一条 SQL 在 Apache Spark 之旅(上)》、《一条 SQL 在 Apache Spark 之旅(中)》 以及 《一条 SQL 在 Apache Spark 之旅(下)》 这三篇文章中介绍了 SQL 从用户提交到最后执行都经历了哪些过程,感兴趣的同学可以去这三篇文章看看。

这篇文章中我们主要来介绍 SQL 查询计划(Query Plan)常见的处理模型(processing model)。数据库的处理模型定义了系统如何运行一个查询计划,不同的工作负载选择不同的处理模型。

在进入下面的文章之前,假设我们有以下的 SQL 查询:

SELECT R.id, S.cdate

FROM R JOIN S

ON R.id = S.id

WHERE S.value > 100

根据之前的文章,我们很快就可以将上面这条 SQL 的查询计划画出来:

dc46725e05139e96d484ad77656ba6c4.png

系统为了处理这个查询计划,主要有三种执行模型:

  • 迭代模型(Iterator Model)

  • 物化模型(Materialization Model)

  • 向量化/批处理模型(Vectorized / Batch Model)

下面我们来简单介绍这三种执行模型的区别。

迭代模型(Iterator Model)

迭代模型又称 Volcano Model 或者 Pipeline Model。这种模型中的查询计划算子(query plan operator)都需要实现 next() 函数:

  • 每次调用的时候,operator 将返回一个元组(tuple)或一个空标记(null),空标记代表数据已经遍历完;

  • operator 需要实现一个循环,其调用子 operator 的 next() 函数,用于从子 operator 中获取数据,然后再处理它。

bb6ac06aca80731b4d82da2aa4456ae0.png

85ed96a98416149985b3c792329f34f1.png

当今世界上绝大多数关系型数据库都是使用迭代模型的,比如 SQLite、MongoDB、Impala、DB2、SQLServer、Greenplum、PostgreSQL、Oracle、MySQL 等。我们熟悉的 Apache Spark 1.x 的 SQL 引擎也是基于这个模型做的(参见 Apache Spark作为编译器:深入介绍新的Tungsten执行引擎)。迭代模型的优点是抽象起来很简单,很容易实现,而且可以通过任意组合算子来表达复杂的查询。但是缺点也很明显,存在大量的虚函数调用,会引起 CPU 的中断,最终影响了执行效率;而且 Joins, Subqueries, Order By 等操作在其子 operator 返回数据之前会被 block 住。

物化模型(Materialization Model)

物化模型的处理方式是:每个 operator 一次处理所有的输入,处理完之后将所有结果一次性输出。由于这种模式中的 operator 其输出“物化”为单个结果,所以称为物化模型。在实现中,DBMS 一般会下推一些 hints 以避免扫描太多的数据。注意,这种模式可以返回物化的行数据或者单列数据。物化模型的处理流程如下:

5870c19634cc72eed236f9712115d6fd.png

物化模型更适合 OLTP 负载,因为这些查询每次只访问小规模的数据,只需要少量的函数调用。

向量化/批处理模型(Vectorized / Batch Model)

Vectorization Model 和 Iterator Model 类似,每个 operator 需要实现一个 next() 函数,但是每次调用 next() 函数会返回一批的元组(tuples)而不是一个元组。在 operator 内部,每次循环都会处理多个元组。批次的大小可以根据硬件或者查询数据进行配置的。可以看出Vectorization Model 是 Iterator Model 和 Materialization Model 的折衷。向量化模型的处理流程如下:

e620b137d40cdd46e7a78858d9f5b4ea.png

Vectorization Model 比较适合 OLAP 查询,因为其大大减少了每个 operator 的调用次数,也就简单减少了虚函数的调用。而且现代编译器和 CPU 在运行简单的循环时,是非常高效的。编译器会自动展开简单的循环,甚至在每个 CPU 指令中产生 SIMD 指令来处理多个元组。

Presto(参见 Aria 项目)、snowflake、SQLServer、Amazon Redshift 等数据库支持这种处理模式。

向量化/批处理模型与大数据

大家熟悉的 Apache Hive 从 0.13.0 版本开始也支持向量化执行模型,参见 HIVE-4160。为了在 Hive 中使用 vectorized query execution,我们必须以 ORC 格式来存储我们的数据,并且将 hive.vectorized.execution.enabled 参数设置为 true(默认是不开启的)。

另外,Apache Spark 2.x 的 SQL 引擎开始也支持向量化执行模型,参见 Apache Spark作为编译器:深入介绍新的Tungsten执行引擎。其效率比 Iterator Model 高出数倍。由于篇幅的原因,我们将在另外一篇文章介绍 Apache Spark 的 Vectorized Query Execution。

猜你喜欢

1、经典Hive-SQL面试题

2、在 Hive 中使用 OpenCSVSerde

3、如果你也想做实时数仓…

4、面试官问我Arrays.sort()为什么可以对int等数组进行排序,我跟面试官扯了半个小时

baf2c69946d578325534739d6cb866e9.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值