欢迎关注大数据技术架构与案例微信公众号:过往记忆大数据
过往记忆博客公众号iteblog_hadoop
欢迎关注微信公众号:
过往记忆大数据
大数据技术博客公众号bigdata_ai
开发爱好者社区:
Java技术范

图文介绍 SQL 的三种查询计划处理模型

我已经在之前的 《一条 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 的查询计划画出来:

query plan
如果想及时了解Spark、Hadoop或者HBase相关的文章,欢迎关注微信公众号:iteblog_hadoop

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

  • 迭代模型(Iterator Model)
  • 物化模型(Materialization Model)
  • 向量化/批处理模型(Vectorized / Batch Model)

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

迭代模型(Iterator Model)

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

  • 每次调用的时候,operator 将返回一个元组(tuple)或一个空标记(null),空标记代表数据已经遍历完;
  • operator 需要实现一个循环,其调用子 operator 的 next() 函数,用于从子 operator 中获取数据,然后再处理它。
Iterator Model
Iterator Model
如果想及时了解Spark、Hadoop或者HBase相关的文章,欢迎关注微信公众号:iteblog_hadoop

当今世界上绝大多数关系型数据库都是使用迭代模型的,比如 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 以避免扫描太多的数据。注意,这种模式可以返回物化的行数据或者单列数据。物化模型的处理流程如下:

Materialization Model
如果想及时了解Spark、Hadoop或者HBase相关的文章,欢迎关注微信公众号:iteblog_hadoop

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

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

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

Materialization Model
如果想及时了解Spark、Hadoop或者HBase相关的文章,欢迎关注微信公众号:iteblog_hadoop

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。

本博客文章除特别声明,全部都是原创!
转载本文请加上:转载自过往记忆(https://www.iteblog.com/)
本文链接: 【图文介绍 SQL 的三种查询计划处理模型】(https://www.iteblog.com/archives/9806.html)
喜欢 (3)
分享 (0)
发表我的评论
取消评论

表情
本博客评论系统带有自动识别垃圾评论功能,请写一些有意义的评论,谢谢!