在bigquery中为_PARTITIONTIME使用子查询不会限制成本

时间:2019-01-10 19:42:16

标签: google-bigquery subquery

当我使用标准SQL在BQ上运行以下查询时,它说它将在运行时处理76.6TB

SELECT 
event_time, user_id, activity_id,dbm_insertion_order_id, dbm_total_media_cost_usd 
FROM `raw.5295.activity_*`
WHERE _PARTITIONTIME >(SELECT * FROM `analytics-dwh.autobidding.activity_list` )
AND timestamp_micros(event_time)  > (SELECT timestamp_micros(MAX(event_time)) from `essence-analytics-dwh.ml_for_autobidding.nest_na_4q18_activity_updated_daily`)
AND _TABLE_SUFFIX IN ('25','20')

analytics-dwh.autobidding.activity_list表只有一列具有唯一的整数列表

如果我从上表中删除了子查询,则该查询在运行时使用的内存不足500GB

SELECT 
event_time, user_id, activity_id,dbm_insertion_order_id, dbm_total_media_cost_usd 
FROM `raw.5295.activity_*`
WHERE _PARTITIONTIME >TIMESTAMP('2018-12-20')
AND timestamp_micros(event_time)  > (SELECT timestamp_micros(MAX(event_time)) from `essence-analytics-dwh.ml_for_autobidding.nest_na_4q18_activity_updated_daily`)
AND _TABLE_SUFFIX IN ('25','20')

为什么在使用子查询时会发生这种情况?有解决方法吗?

谢谢

2 个答案:

答案 0 :(得分:2)

通过查看查询,我假设您要从中选择MIN或MAX日期:

SELECT * FROM `analytics-dwh.autobidding.activity_list`

并将其传递给查询的第二部分

这可以通过在代码内使用BigQuery API来完成,该代码将在两个步骤之间传递值(例如Python或Javascript)

答案 1 :(得分:2)

  

为什么使用子查询会发生这种情况?

通常,当可以在查询开始时就对过滤器进行评估而无需任何子查询评估或数据扫描时,分区修剪将减少查询成本。

您可以了解有关Limiting partitions queried using pseudo columns

的更多信息

因此,在您的第一个查询(您在其中使用子查询)中-修剪没有发生(它不会根据涉及子查询的条件限制使用分区)

在第二个查询中,您使用_PARTITIONTIME >TIMESTAMP('2018-12-20')来限制分区

底线:不能在_PARTITIONTIME上使用包含子查询的过滤器来限制为分区表扫描的分区数。

  

有解决方法吗?

您应该将任务分为两个步骤:使用表analytics-dwh.autobidding.activity_list之外的任何逻辑为_PARTITIONTIME计算过滤器,然后使用它(而不是子查询)-使用您选择的任何client < / p>