我想了解BigQuery中的执行和数据检索逻辑,以便我可以编写更高效的查询。假设我有以下表,每个表都包含大量的行:
table_a
:连接键id
,由date_a
划分,由cluster_a
聚类table_b
:连接键id
,由date_b
分区,由cluster_b
聚类
根据SQL的执行顺序,我们先求出FROM
和JOIN
s语句来确定要查询的数据的总工作集,然后求出WHERE
子句来过滤数据。
那么,假设我有这样一个查询:
查询1:
SELECT
id,
ta.date_a AS date,
ta.cluster_a,
tb.cluster_b
FROM table_a AS ta
LEFT JOIN table_b AS tb
USING (id)
WHERE
ta.date_a = '2022-11-01'
AND tb.date_b = '2022-11-01'
AND ta.cluster_a = 'a'
AND tb.cluster_b = 'b'
和另一个,返回相同的输出:
查询2:
SELECT
id,
ta.date_a AS date,
ta.cluster_a,
tb.cluster_b
FROM (
SELECT
id,
date_a,
cluster_a
FROM table_a
WHERE
date_a = '2022-11-01'
AND cluster_a = 'a'
) AS ta
LEFT JOIN (
SELECT
id,
cluster_b
FROM table_b
WHERE
date_b = '2022-11-01'
AND cluster_b = 'b'
) AS tb
USING (id)
考虑这两个查询:
- Is查询2更有效,因为我在加入之前过滤了
FROM
和JOIN
条款?或者查询1还过滤行数与WHERE
子句做连接之前? - 是否有其他方法可以改进此查询?
基本上,这可以适用于几乎任何数据库:
- 在join 之前最好有更小的表
- 让大表加入小表,而不是让大表加入大表。 SELECT子句中避免不必要的列。
所以query2的性能会更好,因为过滤器是在连接之前应用的,从而产生更小的集合。