我有一个表,其中有50多个记录具有以下结构:
sku STRING,
sale_net STRING,
sold_amount FLOAT64,
dt DATE,
is_promo BOOL
我需要从中选择包含sku
至少一次的sale_nets
和is_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%
是否可以优化我的查询?如何优化?
答案 0 :(得分:2)
通常,对于这种类型的查询,存在子句比使用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 ) );
答案 1 :(得分:2)
如何使用窗口功能?
select *
from (select t.*,
countif(ispromo) over (partition by sku, sale_net) as num_promos
from t
) t
where num_promos > 0;
答案 2 :(得分:1)
select * from src_tbl tbl1
where exists (select * from src_tbl tbl2
where tbl1.sku = tbl2.sku and
tbl1.sale_net = tbl2.sale_net and
tbl2.is_promo = true);
答案 3 :(得分:1)
我不确定这是否对您有用,因为我意识到bigquery的工作与常规db不同。但是我还是会提出我的建议。
首先尝试查找哪个sku有促销。
select sku
from src_tbl
group by sku
having COUNT( case when is_promo then 1 end) > 0
如果该工作尝试使用部分结果或将其另存为临时表
SELECT *
FROM src_tbl
WHERE sku IN ( select sku
from src_tbl
group by sku
having COUNT( case when is_promo then 1 end) > 0
)
区别在于您仅在全表扫描中查找带有促销的所有sku,然后进行另一次全表扫描以返回具有匹配sku的行。而不是对每一行进行全面扫描以查找该行是否有促销。
答案 4 :(得分:1)
以下是用于BigQuery标准SQL
#standardSQL
SELECT *
FROM `project.dataset.src_tbl`
WHERE (sku, sale_net) IN (
SELECT DISTINCT AS STRUCT sku, sale_net
FROM `project.dataset.src_tbl`
WHERE is_promo
)
答案 5 :(得分:1)
加入应该有效,它比WHERE IN
类型查询更有效地实现:
WITH promo_sku AS (
SELECT DISTINCT sku, sale_net
FROM `project.dataset.src_tbl`
WHERE is_promo = true
)
SELECT *
FROM src_tbl tbl1
JOIN promo_sku ON promo_sku.sku = tbl1.sku AND promo_sku.sale_net = tbl1.sale_net