在PySpark中优化大表加入

时间:2016-11-09 23:22:54

标签: query-optimization pyspark partition pyspark-sql

我有一个大的事实表,每天大约500M行。该表由region_date分区。

我必须每天扫描6个月的数据,基于id& amp;和外部联接与另一个较小的子集(1M行)。 date列并计算两个聚合值:如果id存在于右表中,则sum(fact)&总和(事实)

我的SparkSQL看起来像这样:

SELECT
    a.region_date,
    SUM(case
          when t4.id is null then 0
          else a.duration_secs
        end) matching_duration_secs
    SUM(a.duration_secs) total_duration_secs
 FROM fact_table a LEFT OUTER JOIN id_lookup t4
       ON a.id = t4.id
      and a.region_date = t4.region_date
 WHERE a.region_date >= CAST(date_format(DATE_ADD(CURRENT_DATE,-180), 'yyyyMMdd') AS BIGINT)
   AND a.is_test = 0
   AND a.desc = 'VIDEO'
GROUP BY a.region_date

优化和分发/分区数据的最佳方法是什么?该查询现在运行超过3个小时。我试过了spark.sql.shuffle.partitions = 700

如果我在" id"汇总每日数据等级,它每天大约500万行。我应该首先汇总数据然后再加入吗?

谢谢,

RAM中。

1 个答案:

答案 0 :(得分:0)

由于您的查询中存在一些过滤条件,我认为您可以将查询拆分为两个查询以首先减少数据量。

       table1 = select * from fact_table 
       WHERE a.region_date >= CAST(date_format(DATE_ADD(CURRENT_DATE,-180), 'yyyyMMdd') AS BIGINT)
       AND a.is_test = 0
       AND a.desc = 'VIDEO'

然后你可以使用比原始表小得多的新表加入id_lookup