BigQuery按嵌套列特殊值索引匹配另一嵌套列值及查询优化
优化方案
首先明确:不需要重构表结构,仅通过SQL语法优化即可大幅提升查询效率,同时直接输出你需要的最终结果。
核心优化逻辑
- 去掉所有冗余的分商品CTE、多表关联逻辑,利用两个嵌套数组下标一一对应的特性,仅做一次对齐展开即可
- 用窗口函数直接统计每个订单的最高下单量、以及达到最高下单量的商品数量,一步完成冲突过滤
优化后SQL代码
WITH LATEST_ORDERS AS ( -- 取每个id的最新订单,逻辑和原查询一致 SELECT * EXCEPT(rn) FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY id ORDER BY update_time DESC) AS rn FROM mycompany.engagement.products_ordered ) WHERE rn = 1 ), ALIGNED_ITEMS AS ( -- 按索引对齐展开商品名称和对应下单量,仅需一次UNNEST SELECT lo.id, lo.username, lo.update_time, p.item AS product_name, o.item AS order_count, -- 统计当前订单的最高下单量 MAX(o.item) OVER (PARTITION BY lo.id) AS max_order_count, -- 统计当前订单里达到最高下单量的商品数量 SUM(CASE WHEN o.item = MAX(o.item) OVER (PARTITION BY lo.id) THEN 1 ELSE 0 END) OVER (PARTITION BY lo.id) AS max_count_num FROM LATEST_ORDERS lo, UNNEST(lo.products.list) p WITH OFFSET pos, UNNEST(lo.ordered.list) o WITH OFFSET pos WHERE p.pos = o.pos -- 按下标对齐,确保商品和下单量对应 ) -- 直接过滤出唯一最高下单量的商品,输出需要的字段 SELECT username, update_time, product_name AS top_ordered_product, order_count AS top_order_count FROM ALIGNED_ITEMS WHERE order_count = max_order_count -- 取下单量最高的商品 AND max_count_num = 1 -- 排除多个商品同为最高的冲突情况 AND order_count > 0 -- 过滤最高下单量为0的情况
性能提升说明
原查询的性能瓶颈不是CTE本身,而是多次重复UNNEST同一个数组、多次关联相同数据集:
- 原查询对products.list做了3次UNNEST,对ordered.list做了1次UNNEST,加4次LEFT JOIN
- 优化后仅对两个数组各做1次UNNEST,无额外关联操作,1万行规模的表查询耗时可以降到1秒以内
结果说明
上述查询直接输出用户名、更新时间、最高下单量商品、最高下单数,完全不需要Python后处理,输出结果和你的需求完全匹配,样例数据返回结果如下:
| username | update_time | top_ordered_product | top_order_count |
|---|---|---|---|
| a_turing | 2021-08-14 20:03:22.100846 UTC | Pear | 2 |
| g_hopper | 2021-08-15 09:36:48.220464 UTC | Orange | 2 |
| a_lovelace | 2021-08-15 13:59:03.441506 UTC | Orange | 1 |
用户v_nabokov因为两个商品下单量同为最高,会被过滤,符合需求。
内容的提问来源于stack exchange,提问作者randomdatascientist
相关产品推荐
相关产品推荐

