首页 > 解决方案 > 是否有任何更快、更少资源消耗的查询用于相同目的?

问题描述

我有一个包含 50+ 百万条记录的表,其结构如下:

sku STRING,
sale_net STRING,
sold_amount FLOAT64,
dt DATE,
is_promo BOOL

我需要从中选择至少有一次的sku记录sale_netsis_promo = true

例如,如果表只有 3 条记录:

sku1 sn1 123 01.01.2018 false
sku1 sn1 456 02.01.2018 true
sku2 sn1 321 01.01.2018 false //this sku-sale_net pair don't have is_promo = true records at other dates

我的查询应该只选择前两个。

我写了这个查询:

select * 
from src_tbl tbl1 
where (select count(*) 
       from src_tbl tbl2 
       where tbl1.sku = tbl2.sku 
         and tbl1.sale_net = tbl2.sale_net 
         and is_promo = true) > 0;

但由于资源过度使用,它无法在更大的数据库上执行:

Resources exceeded during query execution: The query could not be executed in the allotted memory. Peak usage: 105% of limit. Top memory consumer(s): aggregate functions and GROUP BY clauses: 93% other/unattributed: 7%

是否可以优化我的查询以及如何优化?

标签: sqlgoogle-bigquery

解决方案


一般来说,对于这种类型的查询,exists 子句比使用 count() 更好,因为这意味着数据库知道它可以在找到一条匹配记录后停止工作,这样的事情可能会起作用:

 select * 
 from src_tbl tbl1 
 where exists (select 1 
               from src_tbl tbl2 
               where tbl1.sku = tbl2.sku 
                and tbl1.sale_net = tbl2.sale_net 
                and tbl2.is_promo = true);

如果这仍然不起作用,您可以尝试完全避免使用相关子查询,例如:

 select * 
 from src_tbl tbl1 
 where tbl1.sku in( (select tbl2.sku 
               from src_tbl tbl2 
               where tbl2.is_promo = true
               group by tbl2.sku ) );

推荐阅读