为啥 Spark 以不同的方式解释这两个查询?

Posted

技术标签:

【中文标题】为啥 Spark 以不同的方式解释这两个查询?【英文标题】:Why Spark explain these two query differently?为什么 Spark 以不同的方式解释这两个查询? 【发布时间】:2017-06-08 15:13:53 【问题描述】:

所以我有这两个查询来实现相同的目标。使用 Spark-SQL。

查询 A:

SELECT * FROM inspex.defect_parquet a
INNER JOIN inspex.layer_parquet b
ON a.id = b.id 
AND b.name = 'Example1';

查询 B:

SELECT * FROM inspex.defect_parquet 
WHERE inspex.layer_scan_index  
IN    (SELECT layer_scan_index
      FROM inspex.layer_parquet
      WHERE name = 'Example1');

defect_parquet 是一个很大的表,layer_parquet 是一个几百 kb 的小表。

查询 B 比 A 快 80%。当我看到 Spark 如何运行它的解释时。这是查询A: 这是查询 B:

似乎 Spark 以不同的方式处理这些问题。有人可以向我解释一下吗?为什么查询 B 更快?

【问题讨论】:

非常有趣..通过第一次查看您的查询,您的第二个查询似乎将数据集过滤到最小,并传递给大数据选择(通过广播哈希连接,因此广播结果大小较小)。这就是它快速的原因。但令人惊讶的事实是加载 7 027 202 行它显示不同的时间(第一次查询 13.2 秒和 3.2 秒)对于大数据集,即 inspex.defect_parquet 在你的 2 个统计图中 【参考方案1】:

我认为统计数据说明了一切:

两个版本都使用广播加入 但是,在第二个查询中,您在子查询中创建项目,因此输出表要小得多 - 这会导致广播大小更小,时间更短 第一个查询尝试预过滤大型数据集,但没有进行太多更改 - 数据集仍然很大,因此此优化只会减慢您的第一个查询

【讨论】:

“项目”到底是什么意思? @Jesse Projection 表示从所有列中仅选择少数列。因此,不会发送完整的源数据集,而只会发送少数选定的列。在 SQL 中投影在 SELECT 中 我认为您的第三点可能是原因。因为我又查了一下解释,发现投影栏后好像也少了很多。但是查询 B 避免了大表中的过滤器。谢谢。

以上是关于为啥 Spark 以不同的方式解释这两个查询?的主要内容,如果未能解决你的问题,请参考以下文章

为啥这两个 NHibernate 查询会产生不同的结果?

为啥 Snowflake 中这两个相似的查询具有非常不同的性能?

Spark SQL:为啥一个查询有两个作业?

为啥这两个结构在受生命周期影响的方式上有所不同

尽管代码相同,为啥这两个 html/css 文件的工作方式不同? [关闭]

为啥 apache spark 中的这两个阶段计算相同的东西?