这有点味道 - 这是一个从水晶报告中调用的查询,该报告使用分成两个纸箱的纸箱编号进行搜索并返回纸箱编号,数量,从原始数量中删除的数量,用户和拖车号码,如果它已经加载到一个。
查询的第一部分效果很好,遗憾的是所有数据都会在30天后归档,并且存档量很大!添加归档部分后,此查询可能需要30到45分钟才能运行,这太长了。任何人都可以帮我优化这个查询,以便它可以更快地运行吗?
非常感谢,7岁。
SELECT *
FROM
(SELECT menu_optn_name,
tran_nbr,
seq_nbr,
cntr_nbr,
ch.total_qty ,
ptt.create_date_time,
um.user_name,
ch.trlr_nbr,
(SELECT sum(ref_field_2)
FROM prod_trkg_tran
WHERE menu_optn_name = 'RF Split/Comb {Carton}'
AND cntr_nbr = '0030651942') AS Total
FROM prod_trkg_tran ptt
INNER JOIN user_master um ON um.emplye_id = ptt.user_id
LEFT OUTER JOIN carton_hdr ch ON ch.carton_nbr = ptt.cntr_nbr
WHERE menu_optn_name = 'RF Split/Comb {Carton}'
AND ptt.cntr_nbr = '0030651942'
GROUP BY menu_optn_name,
tran_nbr,
seq_nbr,
cntr_nbr,
ch.total_qty,
ptt.create_date_time,
um.user_name,
ch.trlr_nbr
UNION SELECT menu_optn_name,
tran_nbr,
seq_nbr,
cntr_nbr,
ch.total_qty,
ptt.create_date_time,
um.user_name,
ch.trlr_nbr,
(SELECT sum(ref_field_2)
FROM prod_trkg_tran
WHERE menu_optn_name = 'RF Split/Comb {Carton}'
AND cntr_nbr NOT IN
(SELECT cntr_nbr
FROM prod_trkg_tran ptt
LEFT OUTER JOIN carton_hdr ch ON ch.carton_nbr = ptt.cntr_nbr
WHERE menu_optn_name = 'RF Split/Comb {Carton}'
AND ptt.cntr_nbr = '0030651942')
AND tran_nbr IN
(SELECT tran_nbr
FROM prod_trkg_tran ptt
LEFT OUTER JOIN carton_hdr ch ON ch.carton_nbr = ptt.cntr_nbr
WHERE menu_optn_name = 'RF Split/Comb {Carton}'
AND ptt.cntr_nbr = '0030651942')) AS Total
FROM prod_trkg_tran ptt
INNER JOIN user_master um ON um.emplye_id = ptt.user_id
LEFT OUTER JOIN carton_hdr ch ON ch.carton_nbr = ptt.cntr_nbr
WHERE cntr_nbr NOT IN
(SELECT cntr_nbr
FROM prod_trkg_tran ptt
LEFT OUTER JOIN carton_hdr ch ON ch.carton_nbr = ptt.cntr_nbr
WHERE menu_optn_name = 'RF Split/Comb {Carton}'
AND ptt.cntr_nbr = '0030651942')
AND tran_nbr IN
(SELECT tran_nbr
FROM prod_trkg_tran ptt
LEFT OUTER JOIN carton_hdr ch ON ch.carton_nbr = ptt.cntr_nbr
WHERE menu_optn_name = 'RF Split/Comb {Carton}'
AND ptt.cntr_nbr = '0030651942')
GROUP BY menu_optn_name,
tran_nbr,
seq_nbr,
cntr_nbr,
ch.total_qty,
ptt.create_date_time,
um.user_name,
ch.trlr_nbr)
UNION
SELECT *
FROM
(SELECT menu_optn_name,
tran_nbr,
seq_nbr,
cntr_nbr,
ch.total_qty,
ptt.create_date_time,
um.user_name,
ch.trlr_nbr,
(SELECT sum(ref_field_2)
FROM wm_archive.prod_trkg_tran@awm.corp.*******.com
WHERE menu_optn_name = 'RF Split/Comb {Carton}'
AND cntr_nbr = '0030651942') AS Total
FROM wm_archive.prod_trkg_tran@awm.corp.*******.com ptt
INNER JOIN user_master um ON um.emplye_id = ptt.user_id
LEFT OUTER JOIN carton_hdr ch ON ch.carton_nbr = ptt.cntr_nbr
WHERE menu_optn_name = 'RF Split/Comb {Carton}'
AND ptt.cntr_nbr = '0030651942'
GROUP BY menu_optn_name,
tran_nbr,
seq_nbr,
cntr_nbr,
ch.total_qty,
ptt.create_date_time,
um.user_name,
ch.trlr_nbr
UNION SELECT menu_optn_name,
tran_nbr,
seq_nbr,
cntr_nbr,
ch.total_qty,
ptt.create_date_time,
um.user_name,
ch.trlr_nbr,
(SELECT sum(ref_field_2)
FROM wm_archive.prod_trkg_tran@awm.corp.*******.com
WHERE menu_optn_name = 'RF Split/Comb {Carton}'
AND cntr_nbr NOT IN
(SELECT cntr_nbr
FROM wm_archive.prod_trkg_tran@awm.corp.*******.com ptt
LEFT OUTER JOIN wm_archive.carton_hdr@awm.corp.*******.com ch ON ch.carton_nbr = ptt.cntr_nbr
WHERE menu_optn_name = 'RF Split/Comb {Carton}'
AND ptt.cntr_nbr = '0030651942')
AND tran_nbr IN
(SELECT tran_nbr
FROM wm_archive.prod_trkg_tran@awm.corp.*******.com ptt
LEFT OUTER JOIN wm_archive.carton_hdr@awm.corp.*******.com ch ON ch.carton_nbr = ptt.cntr_nbr
WHERE menu_optn_name = 'RF Split/Comb {Carton}'
AND ptt.cntr_nbr = '0030651942')) AS Total
FROM wm_archive.prod_trkg_tran@awm.corp.*******.com ptt
INNER JOIN user_master um ON um.emplye_id = ptt.user_id
LEFT OUTER JOIN wm_archive.carton_hdr@awm.corp.*******.com ch ON ch.carton_nbr = ptt.cntr_nbr
WHERE cntr_nbr NOT IN
(SELECT cntr_nbr
FROM wm_archive.prod_trkg_tran@awm.corp.*******.com ptt
LEFT OUTER JOIN wm_archive.carton_hdr@awm.corp.*******.com ch ON ch.carton_nbr = ptt.cntr_nbr
WHERE menu_optn_name = 'RF Split/Comb {Carton}'
AND ptt.cntr_nbr = '0030651942')
AND tran_nbr IN
(SELECT tran_nbr
FROM wm_archive.prod_trkg_tran@awm.corp.*******.com ptt
LEFT OUTER JOIN wm_archive.carton_hdr@awm.corp.*******.com ch ON ch.carton_nbr = ptt.cntr_nbr
WHERE menu_optn_name = 'RF Split/Comb {Carton}'
AND ptt.cntr_nbr = '0030651942')
GROUP BY menu_optn_name,
tran_nbr,
seq_nbr,
cntr_nbr,
ch.total_qty,
ptt.create_date_time,
um.user_name,
ch.trlr_nbr)
WHERE rownum <=2;
答案 0 :(得分:0)
我看到这个查询有两种可能的优化。
首先是:
SELECT key, (SELECT SUM(value) FROM table WHERE condition) AS Total
FROM table WHERE condition
GROUP BY key
在功能上等同于:
SELECT key, SUM(value)
FROM table WHERE condition
GROUP BY key
......但可能效率低得多。
第二个是:
SELECT x,y,z FROM table WHERE condition_1 GROUP BY x,y
UNION
SELECT x,y,z FROM table WHERE condition_2 GROUP BY x,y
在功能上等同于:
SELECT x,y,z FROM table WHERE condition_1 OR condition_2 GROUP BY x,y
也就是说,如果condition_1和condition_2只引用出现在GROUP BY子句中的列,就像你的情况一样。顺序可能存在一些差异,但如果需要,可以使用显式ORDER BY子句来解决这些差异。
也就是说,消除4个子选择和2个联合似乎是可能的。考虑到WHERE过滤器的所有列都位于prod_trkg_tran表中,您还可以删除一些LEFT JOIN。所以它看起来像这样:
select * from (
select menu_optn_name, tran_nbr, seq_nbr, cntr_nbr, ch.total_qty, ptt.create_date_time, um.user_name, ch.trlr_nbr, sum(ref_field_2) as Total
from prod_trkg_tran ptt
inner join user_master um on um.emplye_id = ptt.user_id
left outer join carton_hdr ch on ch.carton_nbr = ptt.cntr_nbr
where (menu_optn_name = 'RF Split/Comb {Carton}' and ptt.cntr_nbr = '0030651942') or (
cntr_nbr not in (
select cntr_nbr
from prod_trkg_tran
where menu_optn_name = 'RF Split/Comb {Carton}' and cntr_nbr = '0030651942'
) and
tran_nbr in (
select tran_nbr
from prod_trkg_tran
where menu_optn_name = 'RF Split/Comb {Carton}' and cntr_nbr = '0030651942'
)
)
group by menu_optn_name, tran_nbr, seq_nbr, cntr_nbr, ch.total_qty, ptt.create_date_time, um.user_name, ch.trlr_nbr
)
union
select * from (
select menu_optn_name, tran_nbr, seq_nbr, cntr_nbr, ch.total_qty, ptt.create_date_time, um.user_name, ch.trlr_nbr, sum(ref_field_2) as Total
from wm_archive.prod_trkg_tran@awm.corp.*******.com ptt
inner join user_master um on um.emplye_id = ptt.user_id
left outer join carton_hdr ch on ch.carton_nbr = ptt.cntr_nbr
where (menu_optn_name = 'RF Split/Comb {Carton}' and ptt.cntr_nbr = '0030651942') or (
cntr_nbr not in (
select cntr_nbr
from wm_archive.prod_trkg_tran@awm.corp.*******.com
where menu_optn_name = 'RF Split/Comb {Carton}' and cntr_nbr = '0030651942'
) and
tran_nbr in (
select tran_nbr
from wm_archive.prod_trkg_tran@awm.corp.*******.com ptt
where menu_optn_name = 'RF Split/Comb {Carton}' and cntr_nbr = '0030651942'
)
)
group by menu_optn_name, tran_nbr, seq_nbr, cntr_nbr, ch.total_qty, ptt.create_date_time, um.user_name, ch.trlr_nbr
)
where rownum <=2;
还有第三个优化。 user_master上的INNER JOIN可以从内部选择移出到外部联合。但我怀疑这次加入的成本是多少。