以下查询将永远运行。有人可以告诉我如何改善其表现吗?
Query: update fsa_ip_mth_end_fin_aggregate tbl2
set (team_acip_gss_sls_cry_am,team_sr_gss_sls_cry_am) =
(select acip_gss_sls_cry_am , sr_gss_sls_cry_am
from (select agg.current_fsa_ip_id current_fsa_ip_id,
sum(base1.sr_gss_sls_cry_am) sr_gss_sls_cry_am,
sum(base1.acip_gss_sls_cry_am) acip_gss_sls_cry_am
from ip_dim base,
ip_dim member,
ip_team_hierarchy_brdg,
fsa_ip_mth_end_fin_aggregate base1,
fsa_ip_mth_end_fin_aggregate agg
where ip_team_hierarchy_brdg.base_ip_dim_id = base.ip_dim_id
and ip_team_hierarchy_brdg.member_ip_dim_id = member.ip_dim_id
and ip_team_hierarchy_brdg.active_in = 'Y'
and base.dim_active_in = 'Y'
and member.dim_active_in = 'Y'
and base1.current_fsa_ip_id = base.current_fsa_ip_id
and agg.current_fsa_ip_id = member.current_fsa_ip_id
and ip_team_hierarchy_brdg.allocation_factor != 0
and agg.current_fsa_ip_id = base1.current_fsa_ip_id
group by agg.current_fsa_ip_id) tbl1
where tbl1.current_fsa_ip_id = tbl2.current_fsa_ip_id)
where exists
(select sr_gss_sls_cry_am,acip_gss_sls_cry_am
from (select agg.current_fsa_ip_id current_fsa_ip_id,
sum(base1.sr_gss_sls_cry_am) sr_gss_sls_cry_am,
sum(base1.acip_gss_sls_cry_am) acip_gss_sls_cry_am
from ip_dim base,
ip_dim member,
ip_team_hierarchy_brdg,
fsa_ip_mth_end_fin_aggregate base1,
fsa_ip_mth_end_fin_aggregate agg
where ip_team_hierarchy_brdg.base_ip_dim_id = base.ip_dim_id
and ip_team_hierarchy_brdg.member_ip_dim_id = member.ip_dim_id
and ip_team_hierarchy_brdg.active_in = 'Y'
and base.dim_active_in = 'Y'
and member.dim_active_in = 'Y'
and base1.current_fsa_ip_id = base.current_fsa_ip_id
and agg.current_fsa_ip_id = member.current_fsa_ip_id
and ip_team_hierarchy_brdg.allocation_factor != 0
and agg.current_fsa_ip_id = base1.current_fsa_ip_id
group by agg.current_fsa_ip_id) tbl1
where tbl1.current_fsa_ip_id = tbl2.current_fsa_ip_id);
我尝试了语法:
update (select query...)
set (team_acip_gss_sls_cry_am,team_sr_gss_sls_cry_am) = (select query...)
但由于涉及的分组/汇总功能,这不起作用。
我也试过'IN'而不是EXISTS。两者的性能几乎相同。请指导我这方面。
答案 0 :(得分:0)
我将不得不花费更多时间来剖析您的查询,但看起来您在子查询中有未使用的表。查询优化器应该省略它们,但如果不是,则会出现交叉连接和大量行计数通货膨胀。
更新:有很多缺少的连接条件,我甚至无法告诉您要使用此查询实现的目标。 “ip_dim member”和任何其他表之间的关系在哪里? “ip_team_hierarchy_brdg”和“ip_dim base”如何与“fsa_ip_mth_end_fin_aggregate agg”和“fsa_ip_mth_end_fin_aggregate base1”相关联? fsa_ip_mth_end_fin_aggregate上自联接的目的是什么?如果记录之间存在层次关系,则不应在两侧加入相同的字段。
更新2:既然您已经向我们提供了整个查询,那么至少看起来没有任何交叉连接。除了其他人提供的关于确保你有适当索引的建议之外,我对重复的子查询持怀疑态度。第二次尝试你是在正确的轨道上。子查询可以移动到UPDATE
的表引用中,但是您需要将表更新与聚合分开。我重构了您的查询以使用ANSI JOIN来更容易地进行故障排除,并移动了子查询:
update fsa_ip_mth_end_fin_aggregate tbl2
join (select agg.current_fsa_ip_id current_fsa_ip_id,
sum(base1.sr_gss_sls_cry_am) sr_gss_sls_cry_am,
sum(base1.acip_gss_sls_cry_am) acip_gss_sls_cry_am
from ip_dim base
join ip_team_hierarchy_brdg on ip_team_hierarchy_brdg.base_ip_dim_id = base.ip_dim_id
join ip_dim member on ip_team_hierarchy_brdg.member_ip_dim_id = member.ip_dim_id
join fsa_ip_mth_end_fin_aggregate base1 on base1.current_fsa_ip_id = base.current_fsa_ip_id
join fsa_ip_mth_end_fin_aggregate agg on agg.current_fsa_ip_id = member.current_fsa_ip_id
and agg.current_fsa_ip_id = base1.current_fsa_ip_id
where ip_team_hierarchy_brdg.active_in = 'Y'
and base.dim_active_in = 'Y'
and member.dim_active_in = 'Y'
and ip_team_hierarchy_brdg.allocation_factor != 0
group by agg.current_fsa_ip_id
) tbl1
on tbl1.current_fsa_ip_id = tbl2.current_fsa_ip_id
set tbl2.team_acip_gss_sls_cry_am = tbl1.acip_gss_sls_cry_am,
tbl2.team_sr_gss_sls_cry_am = tbl1.sr_gss_sls_cry_am
这是MySQL语法,我刚才意识到你没有指定你的DBMS。 SQL Server对多表UPDATE
的语法略有不同,我不确定其他人。
如果我错了并且重复的子查询不是罪魁祸首,那么这个查询结构应该至少可以更容易地优化聚合子查询。