Bigquery:按 _PARTITIONTIME 过滤不会在 LEFT JOIN 上传播
Posted
技术标签:
【中文标题】Bigquery:按 _PARTITIONTIME 过滤不会在 LEFT JOIN 上传播【英文标题】:Bigquery: Filter by _PARTITIONTIME doesn't propagate on LEFT JOIN 【发布时间】:2019-05-31 10:17:49 【问题描述】:我有 2 个分区表:
表 1:
|user_id|request_id|
表 2:
|ip|user_id|request_id|
我想从 partition_table2 获取所有 ip: - 用户数(来自 partition_table1) - 用户请求(来自 partition_table1) - 用户请求(来自 partition_table2)用户(来自 partition_table1)
信息: ip与表1中的request_id相关,因为一个user_id可以有多个ip。
问题: 当我在主查询中按 _PARTITIONTIME 过滤时,当我执行 LEFT JOIN 时,它不会传播到 WITH 查询,但是当我执行 INNER JOIN 时,会传播按 _PARTITIONTIME 过滤。
分区修剪似乎不起作用:https://cloud.google.com/bigquery/docs/querying-partitioned-tables 用于 LEFT JOIN
我的查询:
WITH
users_info AS (
SELECT
t2.ip,
t1.user_id,
COUNT(DISTINCT t1.request_id) AS user_requests,
t1._PARTITIONTIME AS date
FROM partitioned_table1 t1
INNER JOIN partition_table2 t2
ON t1.request_id = t2.request_id
AND t1._PARTITIONTIME = t2._PARTITIONTIME
GROUP BY t2.ip, t1.user_id, t1._PARTITIONTIME
)
SELECT
t2.ip,
COUNT(DISTINCT m.user_id) AS users,
COUNT(DISTINCT t2.request_id) AS t2_users_requests,
SUM(m.user_requests) AS t1_users_requests
FROM partition_table2 t2
LEFT JOIN/INNER JOIN users_info m
ON t2.ip=m.ip
AND t2.user_id=m.user_id
AND m.date = t2._PARTITIONTIME
WHERE DATE(t2._PARTITIONTIME) = "2019-05-20"
GROUP BY t2.ip
如果我执行 INNER JOIN,此查询处理 ~4 GB,但使用 LEFT JOIN 它处理 ~3 TB
我做错了什么或者这是预期的行为?
编辑
我需要这个查询来创建一个 VIEW。上面查询中的 Condition(DATE(t2._PARTITIONTIME) = "2019-05-20") 我将在查询 VIEW 时使用它来过滤它。
【问题讨论】:
。 .我认为这种行为是意料之中的。我认为您需要对每个表进行显式分区比较。 这是预期行为。所有 ctes 或子查询都应指定其明确的分区日期或至少日期范围。 【参考方案1】:LEFT OUTER JOIN 右侧的列可能为 NULL,所以是的,BigQuery 实际上需要执行连接来计算结果,而不是提前过滤分区。如果您不希望出现这种行为,请使用子查询,在加入之前过滤_PARTITIONTIME
。
【讨论】:
以上是关于Bigquery:按 _PARTITIONTIME 过滤不会在 LEFT JOIN 上传播的主要内容,如果未能解决你的问题,请参考以下文章
BigQuery 流式传输和分区:_PARTITIONTIME 何时真正评估?
使用 _PARTITIONTIME 从现有表在 BigQuery 中创建聚簇表
如果标准 SQL 不提供 _PARTITIONTIME 字段,我如何在 BigQuery 中查询流缓冲区