问题描述
BigQuery 的 documentation on cost optimization 声明:
BigQuery 可以提供令人难以置信的性能,因为它将数据存储为列式数据结构。这意味着 SELECT * 是查询数据的最昂贵的方式。这是因为它将对表中存在的每一列执行完整的查询扫描,包括您可能不需要的列。
但是,我在文档中找不到任何讨论 BigQuery 引擎是否优化使用 SELECT *
的子查询/虚拟视图的地方。示例:
(1)
CREATE VIEW my_view AS ( SELECT * FROM my_table );
SELECT a,b FROM my_view -- does this only access {a,b} or all columns?
(2)
SELECT a,b FROM (SELECT * FROM my_table) AS t -- does this only access {a,b} or all columns?
所以问题是:BigQuery 是否优化了子查询/视图 SELECT * 以最小化成本,如果是,它是否可靠地做到了这一点?
解决方法
编辑:由张云的回答证实。
从我在 GCP 控制台的 BigQuery 编辑器中的摆弄看来,查询计划执行细节反映了顶级查询的最终需求,而不是子查询中的 SELECT *。
在顶级 SELECT 语句中添加一个字段:
- 更改右上角的标记,用于估计将要处理的数据量
- 导致不同的执行细节细分,其中与子查询中读取的表相关的输入语句根据已在顶级查询的字段进行调整。
例如,如果我查询
SELECT a,b FROM (SELECT * FROM my_table) AS t
然后执行计划会写一些类似于:
S00: Input
READ $10:a,$11:b
FROM my_table
而
SELECT a,b,c FROM (SELECT * FROM my_table) AS t
将导致以下结果:
S00: Input
READ $10:a,$11:b,$12:c
FROM my_table
从而提供了 BQ 根据请求的顶级字段优化由内部 SELECT * 语句读取的字段的弱证据。
,BigQuery 是否优化子查询/视图 SELECT * 以最小化成本,
是的。而且您无需猜测。下面的查询使用公共数据集,您将从项目中看到相同的统计数据。
全表查询:
此查询在运行时将处理 280.6 MB。
SubQuery(视图相同)
此查询在运行时将处理 12.6 MB。
如果是这样,它是否可靠?
是的。这是有保证的。