为什么这两个查询之间的性能差异如此之大?

问题描述 投票:0回答:1

有人可以向我解释为什么第一个查询性能良好(仅处理 254KB),而后两个查询则处理 750MB?这些查询之间的唯一区别在于,第一个查询包含硬编码的 ID 列表,第二个查询从表中获取完全相同的 ID 列表(无硬编码),第三个查询从硬编码数组中获取其 ID 列表。

src_id
字段在所有表中的分区相同。

demo_table
包含 270 万条记录,均匀分布在 10,000 个分区中。

id_table
仅包含1个字段和3条记录。

-- this query performs well - only processes 254KB of data.
select *
from `myproject.mydataset.demo_table`
where src_id in ( 1435718211154057483 
                , 1260912821261010025 
                , 3916818671952292004)
;


-- this query performs poorly - processes 750 of data. 
-- the subquery returns only 3 rows, the exact same ids as used above.
select *
from `myproject.mydataset.demo_table`
where src_id in (select src_id from myproject.mydataset.id_table) 
;

-- this query performs poorly - processes 750 of data. 
-- This query example is included only to demonstrate that the performance
-- degradation seems to related to the presence of a subquery.
select *
from `myproject.mydataset.demo_table`
where src_id in (select src_id
                  from unnest((
                          select [ 1435718211154057483 
                                 , 1260912821261010025 
                                 , 3916818671952292004])) as src_id)

看起来 BigQuery 执行查询的方式有所不同,具体取决于

IN
子句是否包含子查询或简单的值列表。

我真正想要完成的是让第二个查询和第一个查询一样工作(没有硬编码)。 谁能向我解释如何构造这个查询以获得更好的性能?

performance google-bigquery partitioning
1个回答
0
投票

根据文档

要限制查询中扫描的分区,请在过滤器中使用常量表达式。如果您在查询过滤器中使用动态表达式,BigQuery 必须扫描所有分区。

您的第一个查询使用常量表达式,即值列表。 您的其他示例不使用常量表达式,它们使用子查询。

© www.soinside.com 2019 - 2024. All rights reserved.