0

我有以下查询:

#standardSQL

WITH users AS (
  SELECT 1 id, 'pieter' name UNION ALL
  SELECT 2   , 'george'      UNION ALL
  SELECT 3   , 'maggie'
),
invoices AS (
  SELECT 1 id, 1 userId, 25.0 amount, 'taxi fee' description UNION ALL
  SELECT 2   , 1       , 300.0      , 'conference ticket'    UNION ALL
  SELECT 3   , 1       , 300.0      , 'hotel room'           UNION ALL
  SELECT 5   , 3       , 70         , 'airbnb'               UNION ALL
  SELECT 6   , 3       , 22         , 'concert ticket'
)
SELECT
  users.id userId,
  users.name userName
FROM 
  users
LEFT JOIN 
  invoices ON invoices.userId = users.id
GROUP BY
  users.id,
  users.name
ORDER BY
  users.id

在这种情况下,查询处理器可以轻松优化(省略)LEFT JOIN 和 GROUP BY 的组合。但是,当我查看查询计划时,BigQuery 仍然执行连接。为什么?我怎样才能避免这种行为?

我的用例:我有一个视图,其中包含一些需要此类连接的字段。我不希望在不查询字段时执行连接。

我正在使用standardSQL方言。

4

1 回答 1

3

让我详细说明我的评论。

您可能不喜欢执行查询的所有不同方式。让我走出 BQ(我对此有所了解,但肯定缺乏深入的知识),并指出一些用于加入和聚合的算法:

  • 加入:嵌套循环
  • join:使用一张表上的索引的嵌套循环
  • join:索引合并
  • join:排序和合并
  • 加入:哈希和匹配,具有内存和内存变体
  • 聚合:基于哈希
  • 聚合:基于排序
  • 聚合:基于索引
  • 以上所有的并行版本

我意识到基于索引的方法不适用于 BQ。但这些是为了给你一种味道。那么,在选择了特定的算法之后,可能还有参数和子方法——使用什么排序算法?有多大的哈希表?如何处理碰撞?BQ 有自己的参数需要设置,涉及并行度和倾斜度。

这些都是优化器解决的难题。编写它们的人每天都来工作(可能是远程工作)。他们有一个选择:

  • 我是否想修复写得不好的查询,而作者应该知道如何写得更好?
  • 我是否想为可能影响所有用户的一般查询类别找出最佳算法和实现?

编辑:

在评论中,OP 指出他/她实际上指的是view。那是完全不同的动物,在这种情况下,连接消除是一种非常合理的优化策略。

于 2018-02-20T20:52:25.560 回答