Bigquery 查询 JOIN 异常缓慢
Bigquery query JOIN unusually slow
我正在尝试 运行 这个查询,但就我有限的理解水平而言,它慢得离谱。
这里是查询:
SELECT
STRFTIME_UTC_USEC(req.date, "%Y-%m-%d") AS day,
HOUR(req.date) AS hour,
10000*(COUNT(req.request_id) - COUNT(resp.request_id)) AS nb_bid_requests,
COUNT(resp.request_id) AS nb_bid_responses,
FROM
[server.Request] req
LEFT JOIN EACH
server.Response resp
ON
req.request_id = resp.request_id
WHERE
DATEDIFF(CURRENT_TIMESTAMP(), req.date) < 3
GROUP EACH BY
day,
hour
ORDER BY
day,
hour
最让我烦恼的是,这个完全相同的查询在具有相同数据集、表和字段(具有相同数据类型和名称)的生产项目上运行得非常好。唯一的区别是Production比Dev有更多的数据。
我在任何情况下都不是 SQL 方面的专家,我很乐意被告知我可以在哪些方面改进查询。
提前致谢。
编辑:您好,问题已解决。
这是由于 request_id 在 server.Response 中重复的大量 request_id 造成的,这减慢了 "a little bit" 查询。
尝试将您的 WHERE
子句向下推到联接内。
BigQuery 的优化器(还)不会将谓词推送到连接内,因此您发布的查询连接了您的 所有 数据,然后对其进行过滤,而不是仅仅连接您关心的部分关于。如果您在请求和响应中都有一个 date
字段,请在连接的两侧放置过滤器!
如果您无法过滤联接的两边,则切换两边,使较小的(过滤后的)table 位于右侧。由于 BQ 连接的实现方式,如果较小的 table 在右侧,它们通常会执行得更好。
SELECT
STRFTIME_UTC_USEC(req.date, "%Y-%m-%d") AS day,
HOUR(req.date) AS hour,
10000*(COUNT(req.request_id) - COUNT(resp.request_id)) AS nb_bid_requests,
COUNT(resp.request_id) AS nb_bid_responses,
FROM
server.Response resp
RIGHT JOIN EACH
(
SELECT *
FROM
[server.Request]
WHERE
DATEDIFF(CURRENT_TIMESTAMP(), date) < 3
) req
ON
req.request_id = resp.request_id
GROUP EACH BY
day,
hour
ORDER BY
day,
hour
我正在尝试 运行 这个查询,但就我有限的理解水平而言,它慢得离谱。
这里是查询:
SELECT
STRFTIME_UTC_USEC(req.date, "%Y-%m-%d") AS day,
HOUR(req.date) AS hour,
10000*(COUNT(req.request_id) - COUNT(resp.request_id)) AS nb_bid_requests,
COUNT(resp.request_id) AS nb_bid_responses,
FROM
[server.Request] req
LEFT JOIN EACH
server.Response resp
ON
req.request_id = resp.request_id
WHERE
DATEDIFF(CURRENT_TIMESTAMP(), req.date) < 3
GROUP EACH BY
day,
hour
ORDER BY
day,
hour
最让我烦恼的是,这个完全相同的查询在具有相同数据集、表和字段(具有相同数据类型和名称)的生产项目上运行得非常好。唯一的区别是Production比Dev有更多的数据。
我在任何情况下都不是 SQL 方面的专家,我很乐意被告知我可以在哪些方面改进查询。
提前致谢。
编辑:您好,问题已解决。 这是由于 request_id 在 server.Response 中重复的大量 request_id 造成的,这减慢了 "a little bit" 查询。
尝试将您的 WHERE
子句向下推到联接内。
BigQuery 的优化器(还)不会将谓词推送到连接内,因此您发布的查询连接了您的 所有 数据,然后对其进行过滤,而不是仅仅连接您关心的部分关于。如果您在请求和响应中都有一个 date
字段,请在连接的两侧放置过滤器!
如果您无法过滤联接的两边,则切换两边,使较小的(过滤后的)table 位于右侧。由于 BQ 连接的实现方式,如果较小的 table 在右侧,它们通常会执行得更好。
SELECT
STRFTIME_UTC_USEC(req.date, "%Y-%m-%d") AS day,
HOUR(req.date) AS hour,
10000*(COUNT(req.request_id) - COUNT(resp.request_id)) AS nb_bid_requests,
COUNT(resp.request_id) AS nb_bid_responses,
FROM
server.Response resp
RIGHT JOIN EACH
(
SELECT *
FROM
[server.Request]
WHERE
DATEDIFF(CURRENT_TIMESTAMP(), date) < 3
) req
ON
req.request_id = resp.request_id
GROUP EACH BY
day,
hour
ORDER BY
day,
hour