【发布时间】:2020-09-28 15:23:14
【问题描述】:
向 GBQ 专家提问。
这里有两个目的相同的查询
first
SELECT
fullVisitorId AS userid,
CONCAT(fullVisitorId, visitStartTime) AS session,
visitStartTime + (hits[
OFFSET(0)].time / 1000) AS eventtime,
date,
trafficSource.campaign,
trafficSource.source,
trafficSource.medium,
trafficSource.adContent,
trafficSource.adwordsClickInfo.campaignId,
geoNetwork.region,
geoNetwork.city,
trafficSource.keyword,
totals.visits AS visits,
device.deviceCategory AS deviceType,
hits[OFFSET(0)].eventInfo.eventAction,
hits[OFFSET(0)].TRANSACTION.transactionId,
hits[OFFSET(0)].TRANSACTION.transactionRevenue,
SUBSTR(channelGrouping,0,3) AS newchannelGrouping
FROM
`some_site.ga_sessions_*`
WHERE
ARRAY_LENGTH(hits) > 0
AND _table_suffix BETWEEN '20200201'
AND '20200201'
AND fullVisitorId IN (
SELECT
DISTINCT(fullVisitorId)
FROM
`some_site.ga_sessions_*`,
UNNEST(hits) AS hits
WHERE
_table_suffix BETWEEN '20200201'
AND '20200201'
AND (hits.TRANSACTION.transactionId != 'None')
)
second
SELECT
fullVisitorId AS userid,
CONCAT(fullVisitorId, visitStartTime) AS session,
visitStartTime + (hits.time / 1000) AS eventtime,
date,
trafficSource.campaign,
trafficSource.source,
trafficSource.medium,
trafficSource.adContent,
trafficSource.adwordsClickInfo.campaignId,
geoNetwork.region,
geoNetwork.city,
trafficSource.keyword,
totals.visits AS visits,
device.deviceCategory AS deviceType,
hits.eventInfo.eventAction,
hits.TRANSACTION.transactionId,
hits.TRANSACTION.transactionRevenue,
SUBSTR(channelGrouping,0,3) AS newchannelGrouping
FROM
`some_site.ga_sessions_*`, UNNEST(hits) hits
WHERE
_table_suffix BETWEEN '20200201' AND '20200201'
AND fullVisitorId IN (
SELECT
DISTINCT(fullVisitorId)
FROM
`some_site.ga_sessions_*`,
UNNEST(hits) AS hits
WHERE
_table_suffix BETWEEN '20200201'
AND '20200201'
AND (hits.TRANSACTION.transactionId != 'None')
)
第一个使用OFFSET 从嵌套字段中提取数据。根据执行详情报告,查询需要大约 1.5 MB 的 shuffle。
第二个查询使用UNNEST 来访问嵌套数据。并且混洗字节的数量约为(!)75 MB
两种情况下处理的数据量相同。
现在的问题是:
这是否意味着根据this article(涉及优化插槽之间的通信)我应该使用OFFSET 而不是UNNEST 来获取存储在嵌套字段中的数据?
谢谢!
【问题讨论】:
-
乍一看,它们并不相同。 OFFSET 示例仅评估 hits 数组的第一个元素,UNNEST 示例公开了更多活动。不明白你在做苹果与橘子的比较。
-
@shollyman 感谢您的评论。
identical in their purpose- 这就是重点。尽管查询的代码不同,但两个查询都返回相同数量的行和列。我相信我明白OFFSET和UNNEST到底是做什么的。问题是为什么 OFFSET 表现更好 -
正如@shollyman 提到的,函数并不相同,除了我们得到相同的输出之外,它们的逻辑不同(以不同的方式编码)。我建议阅读官方documentation 和这个article。
-
@Ines 再次,我明白功能并不相同。我的问题是为什么偏移比 unnest 工作得更快更好。
-
为一个规范的答案提供了赏金,这让我把所有的声誉都放在了这上面。想知道是否有人可以提供解释
标签: google-bigquery offset unnest