经过几天的思考,我仍然坚持这个问题:我有一个表,其中"时间戳"是分区键。此表包含数十亿行。
我还有"时间序列"表,其中包含与特定测量过程相关的时间戳。
使用Spark,我想分析大桌子的内容。当然,进行全表扫描效率不高,并且在时间序列表中进行相当快的查找,我应该只能针对 10k 个分区。
实现这一目标的最有效方法是什么?
SparkSQL是否足够聪明,可以优化这样的东西
sqlContext.sql("""
SELECT timeseries.timestamp, bigtable.value1 FROM timeseries
JOIN bigtable ON bigtable.timestamp = timeseries.timestamp
WHERE timeseries.parameter = 'xyz'
""")
理想情况下,我希望 Cassandra 从timeseries
表中获取时间戳,然后使用它仅从 bigtable
中查询该分区子集。
如果您在查询中添加"解释"调用,您将看到 Catalyst 规划器将为您的查询做什么,但我知道它不会执行您想要的优化。
目前,Catalyst 不支持将联接向下推送到 DataSources,这意味着查询的结构很可能看起来像这样。
Read Data From Table timeseries with predicate parameter = 'xyz'
Read Data From Table bigtable
Join these two results
Filter on bigtable.timestamp == timeseries.timestamp
Spark Cassandra 连接器将从读取的timeseries
表中获得谓词,如果是群集键或分区键,则可以对其进行优化。请参阅 Spark Cassandra Connector 文档。如果它不适合这些下推类别之一,则需要全表扫描,然后在 Spark 中设置筛选器。
由于从表 bigtable
读取数据没有限制,Spark 将指示连接器读取整个表(全表扫描)。
我只能猜测驱动程序所做的优化,但我肯定希望这样的查询来限制 WHERE 上的 JOIN,这意味着您的简单查询将被优化。
我还要做的是为您指出优化Spark SQL的总体方向。看看 Catalyst for Spark SQL,它是一个可以极大地优化查询的工具,一直到物理级别。
以下是其工作原理的细分:深入了解 Spark SQL Catalyst Optimizer
以及指向 git-repo 的链接:Catalyst repo