长查询调优
A long query tuning
我有以下查询,在这个查询中,我选择 ebs tables,自定义 table 有 header_id 并在自定义中填充数据table XXREPORT_L1_TBL。
我想调整这个查询。
[更新] 对查询进行了如下更改:
- 将查询拆分为 3 个不同的插入语句
- 删除了对值进行在线查询的列
在末尾为这些列添加了更新语句。
insert into XX.XXREPORT_L1_TBL ( ORDER_NUMBER
, LINE_NUMBER
, UOM
, CUSTOMER_LENGTH
, THEORETICAL_WEIGHT
, FINISH
, ORDER_QTY_PCS
, ORDER_QTY_KGS
, SALES_VALUE
, TOTAL_VALUE
, ORDERED_QUANTITY
, WIP_ENTITY_ID
, JOB_NAME
, JOB_TYPE
, JOB_STATUS
, JOB_RELEASED_DATE
, DATE_COMPLETED
, DATE_CLOSED
, JOB_CARD_QTY
, ALLOY
, PROFILE
, PROD_QTY_KGS
, COST_KGS_THEORY
, COST_KGS_ACTUAL
)
SELECT
---- Sales Order
xx.order_number
,xx.line_number
,xx.UOM,
xx.customer_length,
xx.theoretical_weight,
xx.finish,
xx.order_qty_pcs,
xx.order_qty_kgs,
xx.sales_value, -- total value / total kgs
xx.total_value, -- line total
xx.ordered_quantity,
-- Production
xx.wip_entity_id,
xx.job_name,
( select case when a.inventory_item_id = 5716770 and a.job_type='NOT CHILD' then 'PARENT'
when a.job_type='CHILD' and a.inventory_item_id is null then 'CHILD'
when a.job_type='NOT CHILD' and a.inventory_item_id is NOT null then 'NOT CHILD' END JOB_TYPE
from ( select disc2.wip_entity_id as wip_entity_id, decode ( nvl(disc2.attribute9,-1) , -1,'NOT CHILD', 'CHILD') job_type, oel.inventory_item_id
from APPS.wip_discrete_jobs disc2, APPS.oe_order_lines_all oel
where oel.line_id(+) = disc2.source_line_id
)a
where a.wip_entity_id = xx.wip_entity_id
) job_type,
( select decode ( xx.status_type, 6, 'Open',
3, 'Open',
4, 'Completed',
LU1.MEANING )
from APPS.FND_LOOKUP_VALUES LU1
where LU1.LOOKUP_TYPE = 'WIP_JOB_STATUS'
AND LU1.LOOKUP_CODE = xx.STATUS_TYPE
) job_status,
xx.job_released_date,
xx.date_completed,
xx.date_closed
,xx.net_quantity as job_card_qty
,xx.alloy
,xx.profile
,xx.prod_qty_kgs
-- Theoretical Order cost
,xx.cost_kgs_theory
-- Actual Order cost
,xx.cost_kgs_actual
from (
select a.*
-- Theoretical Order cost
, DECODE (a.qty_completed * a.customer_length * a.theoretical_weight,0,0,
a.TOT_THEORY_COST_RELIEVED/(a.qty_completed * a.customer_length * a.theoretical_weight) ) as cost_kgs_theory
-- Actual Order cost
, DECODE ( a.qty_completed * a.customer_length * a.theoretical_weight, 0, 0,
a.TOT_ACTUAL_COST_INCURRED/(a.qty_completed * a.customer_length * a.theoretical_weight )) as cost_kgs_actual
from (
select
-- Normal orders, INTERNAL Orders, Crimped Profile (parent jobs)
-- Sales Order
oeh.order_number as order_number
,oel.line_number
,oel.pricing_quantity_uom as UOM
,oel.attribute1 as customer_length
,oel.attribute6 as theoretical_weight
,oel.attribute5 as finish
,oel.attribute18 as order_qty_pcs
,oel.attribute7 as order_qty_kgs
,xx_om.GetLineUnitSellingPrice(oel.line_id) sales_value
,xx_om.GetHeaderUnitSellingPrice(oeh.header_id) total_value
,oel.ordered_quantity ordered_quantity
-- Production
, tbl0.qty_completed as qty_completed
,disc.wip_entity_id as wip_entity_id
,( select wip_entity_name from APPS.wip_entities ent
where ent.wip_entity_id = disc.wip_entity_id) job_name
,disc.status_type
,disc.date_released as job_released_date
, DECODE ( disc.date_completed, NULL, disc.date_completed,
-- my day Definition
to_date(to_char(to_date(TO_CHAR(disc.date_completed- interval '7' hour,'DD-MON-YYYY')||'00:00:00','DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS')) as date_completed
, DECODE ( disc.date_closed, NULL, disc.date_closed,
to_date(to_char(to_date(TO_CHAR(disc.date_closed- interval '7' hour,'DD-MON-YYYY')||'00:00:00','DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS')) as date_closed
, disc.net_quantity
, ( select opr2.quantity_completed
from APPS.wip_operations opr2
where opr2.wip_entity_id = disc.wip_entity_id
and opr2.operation_seq_num = (select max(opr.operation_seq_num)
from APPS.wip_operations opr, APPS.wip_discrete_jobs disc2
where opr.wip_entity_id = disc2.wip_entity_id
and disc2.wip_entity_id = disc.wip_entity_id))* oel.attribute1 * oel.attribute6 as prod_qty_kgs
,oel.attribute4 as alloy
,oel.attribute2 as profile
-- Theoretical Order cost
,tbl0.TOT_THEORY_COST_RELIEVED
-- Actual Order cost
,tbl0.TOT_ACTUAL_COST_INCURRED
from XX.XXREPORT_Lzero_TBL tbl0
join APPS.oe_order_headers_all oeh on oeh.header_id = tbl0.header_id
join APPS.oe_order_lines_all oel on oeh.org_id = oel.org_id and oeh.header_id = oel.header_id
join APPS.xx_assemblies asm on oel.line_id = asm.line_id
join APPS.wip_discrete_jobs disc on disc.primary_item_id = asm.inventory_item_id
where oel.link_to_line_id is null
union
-- Crimped Child Jobs
select
-- Sales Order
oeh.order_number as order_number
,oel.line_number
,oel.pricing_quantity_uom as UOM
,oel.attribute1 as customer_length
,oel.attribute6 as theoretical_weight
,oel.attribute5 as finish
,oel.attribute18 as order_qty_pcs
,oel.attribute7 as order_qty_kgs
,xx_om.GetLineUnitSellingPrice(oel.line_id) sales_value
,xx_om.GetHeaderUnitSellingPrice(oeh.header_id) total_value
,oel.ordered_quantity ordered_quantity
-- Production
, tbl0.qty_completed as qty_completed
,child_jobs.wip_entity_id as wip_entity_id
,( select wip_entity_name from APPS.wip_entities ent
where ent.wip_entity_id = child_jobs.wip_entity_id) job_name
,disc.status_type
,disc.date_released as job_released_date
, DECODE ( disc.date_completed, NULL, disc.date_completed,
to_date(to_char(to_date(TO_CHAR(disc.date_completed-interval '7' hour,'DD-MON-YYYY')||'00:00:00','DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS')) as date_completed
, DECODE ( disc.date_closed, NULL, disc.date_closed,
to_date(to_char(to_date(TO_CHAR(disc.date_closed-interval '7' hour,'DD-MON-YYYY')||'00:00:00','DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS')) as date_closed
, disc.net_quantity
, ( select opr2.quantity_completed
from APPS.wip_operations opr2
where opr2.wip_entity_id = disc.wip_entity_id
and opr2.operation_seq_num = (select max(opr.operation_seq_num)
from APPS.wip_operations opr, APPS.wip_discrete_jobs disc2
where opr.wip_entity_id = disc2.wip_entity_id
and disc.wip_entity_id = disc.wip_entity_id))* oel.attribute1 * oel.attribute6 as prod_qty_kgs
,oel.attribute4 as alloy
,oel.attribute2 as profile
-- Theoretical Order cost
,tbl0.TOT_THEORY_COST_RELIEVED
-- Actual Order cost
,tbl0.TOT_ACTUAL_COST_INCURRED
from XX.XXREPORT_Lzero_TBL tbl0
join APPS.oe_order_headers_all oeh on oeh.header_id = tbl0.header_id
join APPS.oe_order_lines_all oel on oeh.org_id = oel.org_id and oeh.header_id = oel.header_id
join APPS.xx_assemblies asm on oel.line_id = asm.line_id
join APPS.wip_discrete_jobs disc on disc.primary_item_id = asm.inventory_item_id
join ( select wdj2.source_line_id, wdj2.attribute9 child_wip, wdj2.wip_entity_id, wdj2.status_type status_type
from APPS.wip_discrete_jobs wdj2
where attribute9 IS NOT NULL ) child_jobs on child_jobs.child_wip = to_char(disc.wip_entity_id)
where oel.link_to_line_id is null
union
-- Orders with star (*) items need to pick profile and customer length etc from ego_configured_pr_agv view
select
-- Sales Order
oeh.order_number as order_number
,oel.line_number
,oel.pricing_quantity_uom as UOM
,to_char(agv.gx_cp_length) as customer_length
,to_char(agv.gx_cp_th_weight) as theoretical_weight
,agv.gx_cp_surfacetreatment as finish
,oel.attribute18 as order_qty_pcs
, to_char(agv.gx_cp_th_weight * agv.gx_cp_length * oel.ordered_quantity) as order_qty_kgs
,XX.xx_om.GetLineUnitSellingPrice(oel.line_id) sales_value
,XX.xx_om.GetHeaderUnitSellingPrice(oeh.header_id) total_value
,oel.ordered_quantity ordered_quantity
-- Production
, tbl0.qty_completed as qty_completed
,disc.wip_entity_id as wip_entity_id
,( select wip_entity_name from APPS.wip_entities ent
where ent.wip_entity_id = disc.wip_entity_id) job_name
,disc.status_type
,disc.date_released as job_released_date
, DECODE ( disc.date_completed, NULL, disc.date_completed,
to_date(to_char(to_date(TO_CHAR(disc.date_completed-interval '7' hour,'DD-MON-YYYY')||'00:00:00','DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS')) as date_completed
, DECODE ( disc.date_closed, NULL, disc.date_closed,
to_date(to_char(to_date(TO_CHAR(disc.date_closed-interval '7' hour,'DD-MON-YYYY')||'00:00:00','DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS')) as date_closed
, disc.net_quantity
, ( select opr2.quantity_completed
from APPS.wip_operations opr2
where opr2.wip_entity_id = disc.wip_entity_id
and opr2.operation_seq_num = (select max(opr.operation_seq_num)
from APPS.wip_operations opr, APPS.wip_discrete_jobs disc2
where opr.wip_entity_id = disc2.wip_entity_id
and disc2.wip_entity_id = disc.wip_entity_id))* agv.gx_cp_length * agv.gx_cp_th_weight as prod_qty_kgs
,gx_cp_alloy as alloy
,gx_cp_profile_id as profile
-- Theoretical Order cost
,tbl0.TOT_THEORY_COST_RELIEVED
-- Actual Order cost
,tbl0.TOT_ACTUAL_COST_INCURRED
from XX.XXREPORT_Lzero_TBL tbl0
join APPS.oe_order_headers_all oeh on oeh.header_id = tbl0.header_id
join APPS.oe_order_lines_all oel on oeh.org_id = oel.org_id and oeh.header_id = oel.header_id
join APPS.wip_discrete_jobs disc on oel.line_id = disc.source_line_id
join APPS.ego_gx_configured_pr_agv agv on agv.inventory_item_id= oel.inventory_item_id
where oel.link_to_line_id is null
)a
) xx;
几乎可以肯定没有任何简短的解决方案来调整此查询。这里的问题是它的大小和复杂性。表现不佳只是一个后果。
作为第一步,我会考虑从键盘上休息一下。拿起笔和纸,用通俗易懂的英语(或您喜欢的 "human" 语言)写下您希望通过此查询从数据库中得到回答的问题。然后问问自己 什么 columns/variables/attributes 你绝对需要回答这些问题? 也把它们写下来。
现在,您真的需要所有这些列、嵌套连接、选择等来生成这些变量吗?也许吧,但可能不是。这里的关键点是仅关注您需要的 data/information (YAGNI),然后从那里绘制出一张图片,您需要生成能够回答您问题的信息的基本关系。换句话说,由外而内,而不是相反。
我意识到这听起来可能有点抽象和模糊,但重点是保持清晰和简单的代码始终是一场持续的斗争。密切关注手头的 objective 将帮助您远离杂草。
最后说几点比较具体的想法,一目了然:
- 你真的需要那个工会吗?如果可以,尽量不要它。
- 嵌套很糟糕。嵌套嵌套特别糟糕。尽可能保持平整。
- 是否可以将其拆分为独立的、更小的查询?
- 为变量使用更具描述性的名称,明智地添加注释。
- 学习并掌握 SQL EXPLAIN 命令。
我有以下查询,在这个查询中,我选择 ebs tables,自定义 table 有 header_id 并在自定义中填充数据table XXREPORT_L1_TBL。
我想调整这个查询。
[更新] 对查询进行了如下更改:
- 将查询拆分为 3 个不同的插入语句
- 删除了对值进行在线查询的列
在末尾为这些列添加了更新语句。
insert into XX.XXREPORT_L1_TBL ( ORDER_NUMBER , LINE_NUMBER , UOM , CUSTOMER_LENGTH , THEORETICAL_WEIGHT , FINISH , ORDER_QTY_PCS , ORDER_QTY_KGS , SALES_VALUE , TOTAL_VALUE , ORDERED_QUANTITY , WIP_ENTITY_ID , JOB_NAME , JOB_TYPE , JOB_STATUS , JOB_RELEASED_DATE , DATE_COMPLETED , DATE_CLOSED , JOB_CARD_QTY , ALLOY , PROFILE , PROD_QTY_KGS , COST_KGS_THEORY , COST_KGS_ACTUAL ) SELECT ---- Sales Order xx.order_number ,xx.line_number ,xx.UOM, xx.customer_length, xx.theoretical_weight, xx.finish, xx.order_qty_pcs, xx.order_qty_kgs, xx.sales_value, -- total value / total kgs xx.total_value, -- line total xx.ordered_quantity, -- Production xx.wip_entity_id, xx.job_name, ( select case when a.inventory_item_id = 5716770 and a.job_type='NOT CHILD' then 'PARENT' when a.job_type='CHILD' and a.inventory_item_id is null then 'CHILD' when a.job_type='NOT CHILD' and a.inventory_item_id is NOT null then 'NOT CHILD' END JOB_TYPE from ( select disc2.wip_entity_id as wip_entity_id, decode ( nvl(disc2.attribute9,-1) , -1,'NOT CHILD', 'CHILD') job_type, oel.inventory_item_id from APPS.wip_discrete_jobs disc2, APPS.oe_order_lines_all oel where oel.line_id(+) = disc2.source_line_id )a where a.wip_entity_id = xx.wip_entity_id ) job_type, ( select decode ( xx.status_type, 6, 'Open', 3, 'Open', 4, 'Completed', LU1.MEANING ) from APPS.FND_LOOKUP_VALUES LU1 where LU1.LOOKUP_TYPE = 'WIP_JOB_STATUS' AND LU1.LOOKUP_CODE = xx.STATUS_TYPE ) job_status, xx.job_released_date, xx.date_completed, xx.date_closed ,xx.net_quantity as job_card_qty ,xx.alloy ,xx.profile ,xx.prod_qty_kgs -- Theoretical Order cost ,xx.cost_kgs_theory -- Actual Order cost ,xx.cost_kgs_actual from ( select a.* -- Theoretical Order cost , DECODE (a.qty_completed * a.customer_length * a.theoretical_weight,0,0, a.TOT_THEORY_COST_RELIEVED/(a.qty_completed * a.customer_length * a.theoretical_weight) ) as cost_kgs_theory -- Actual Order cost , DECODE ( a.qty_completed * a.customer_length * a.theoretical_weight, 0, 0, a.TOT_ACTUAL_COST_INCURRED/(a.qty_completed * a.customer_length * a.theoretical_weight )) as cost_kgs_actual from ( select -- Normal orders, INTERNAL Orders, Crimped Profile (parent jobs) -- Sales Order oeh.order_number as order_number ,oel.line_number ,oel.pricing_quantity_uom as UOM ,oel.attribute1 as customer_length ,oel.attribute6 as theoretical_weight ,oel.attribute5 as finish ,oel.attribute18 as order_qty_pcs ,oel.attribute7 as order_qty_kgs ,xx_om.GetLineUnitSellingPrice(oel.line_id) sales_value ,xx_om.GetHeaderUnitSellingPrice(oeh.header_id) total_value ,oel.ordered_quantity ordered_quantity -- Production , tbl0.qty_completed as qty_completed ,disc.wip_entity_id as wip_entity_id ,( select wip_entity_name from APPS.wip_entities ent where ent.wip_entity_id = disc.wip_entity_id) job_name ,disc.status_type ,disc.date_released as job_released_date , DECODE ( disc.date_completed, NULL, disc.date_completed, -- my day Definition to_date(to_char(to_date(TO_CHAR(disc.date_completed- interval '7' hour,'DD-MON-YYYY')||'00:00:00','DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS')) as date_completed , DECODE ( disc.date_closed, NULL, disc.date_closed, to_date(to_char(to_date(TO_CHAR(disc.date_closed- interval '7' hour,'DD-MON-YYYY')||'00:00:00','DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS')) as date_closed , disc.net_quantity , ( select opr2.quantity_completed from APPS.wip_operations opr2 where opr2.wip_entity_id = disc.wip_entity_id and opr2.operation_seq_num = (select max(opr.operation_seq_num) from APPS.wip_operations opr, APPS.wip_discrete_jobs disc2 where opr.wip_entity_id = disc2.wip_entity_id and disc2.wip_entity_id = disc.wip_entity_id))* oel.attribute1 * oel.attribute6 as prod_qty_kgs ,oel.attribute4 as alloy ,oel.attribute2 as profile -- Theoretical Order cost ,tbl0.TOT_THEORY_COST_RELIEVED -- Actual Order cost ,tbl0.TOT_ACTUAL_COST_INCURRED from XX.XXREPORT_Lzero_TBL tbl0 join APPS.oe_order_headers_all oeh on oeh.header_id = tbl0.header_id join APPS.oe_order_lines_all oel on oeh.org_id = oel.org_id and oeh.header_id = oel.header_id join APPS.xx_assemblies asm on oel.line_id = asm.line_id join APPS.wip_discrete_jobs disc on disc.primary_item_id = asm.inventory_item_id where oel.link_to_line_id is null union -- Crimped Child Jobs select -- Sales Order oeh.order_number as order_number ,oel.line_number ,oel.pricing_quantity_uom as UOM ,oel.attribute1 as customer_length ,oel.attribute6 as theoretical_weight ,oel.attribute5 as finish ,oel.attribute18 as order_qty_pcs ,oel.attribute7 as order_qty_kgs ,xx_om.GetLineUnitSellingPrice(oel.line_id) sales_value ,xx_om.GetHeaderUnitSellingPrice(oeh.header_id) total_value ,oel.ordered_quantity ordered_quantity -- Production , tbl0.qty_completed as qty_completed ,child_jobs.wip_entity_id as wip_entity_id ,( select wip_entity_name from APPS.wip_entities ent where ent.wip_entity_id = child_jobs.wip_entity_id) job_name ,disc.status_type ,disc.date_released as job_released_date , DECODE ( disc.date_completed, NULL, disc.date_completed, to_date(to_char(to_date(TO_CHAR(disc.date_completed-interval '7' hour,'DD-MON-YYYY')||'00:00:00','DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS')) as date_completed , DECODE ( disc.date_closed, NULL, disc.date_closed, to_date(to_char(to_date(TO_CHAR(disc.date_closed-interval '7' hour,'DD-MON-YYYY')||'00:00:00','DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS')) as date_closed , disc.net_quantity , ( select opr2.quantity_completed from APPS.wip_operations opr2 where opr2.wip_entity_id = disc.wip_entity_id and opr2.operation_seq_num = (select max(opr.operation_seq_num) from APPS.wip_operations opr, APPS.wip_discrete_jobs disc2 where opr.wip_entity_id = disc2.wip_entity_id and disc.wip_entity_id = disc.wip_entity_id))* oel.attribute1 * oel.attribute6 as prod_qty_kgs ,oel.attribute4 as alloy ,oel.attribute2 as profile -- Theoretical Order cost ,tbl0.TOT_THEORY_COST_RELIEVED -- Actual Order cost ,tbl0.TOT_ACTUAL_COST_INCURRED from XX.XXREPORT_Lzero_TBL tbl0 join APPS.oe_order_headers_all oeh on oeh.header_id = tbl0.header_id join APPS.oe_order_lines_all oel on oeh.org_id = oel.org_id and oeh.header_id = oel.header_id join APPS.xx_assemblies asm on oel.line_id = asm.line_id join APPS.wip_discrete_jobs disc on disc.primary_item_id = asm.inventory_item_id join ( select wdj2.source_line_id, wdj2.attribute9 child_wip, wdj2.wip_entity_id, wdj2.status_type status_type from APPS.wip_discrete_jobs wdj2 where attribute9 IS NOT NULL ) child_jobs on child_jobs.child_wip = to_char(disc.wip_entity_id) where oel.link_to_line_id is null union -- Orders with star (*) items need to pick profile and customer length etc from ego_configured_pr_agv view select -- Sales Order oeh.order_number as order_number ,oel.line_number ,oel.pricing_quantity_uom as UOM ,to_char(agv.gx_cp_length) as customer_length ,to_char(agv.gx_cp_th_weight) as theoretical_weight ,agv.gx_cp_surfacetreatment as finish ,oel.attribute18 as order_qty_pcs , to_char(agv.gx_cp_th_weight * agv.gx_cp_length * oel.ordered_quantity) as order_qty_kgs ,XX.xx_om.GetLineUnitSellingPrice(oel.line_id) sales_value ,XX.xx_om.GetHeaderUnitSellingPrice(oeh.header_id) total_value ,oel.ordered_quantity ordered_quantity -- Production , tbl0.qty_completed as qty_completed ,disc.wip_entity_id as wip_entity_id ,( select wip_entity_name from APPS.wip_entities ent where ent.wip_entity_id = disc.wip_entity_id) job_name ,disc.status_type ,disc.date_released as job_released_date , DECODE ( disc.date_completed, NULL, disc.date_completed, to_date(to_char(to_date(TO_CHAR(disc.date_completed-interval '7' hour,'DD-MON-YYYY')||'00:00:00','DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS')) as date_completed , DECODE ( disc.date_closed, NULL, disc.date_closed, to_date(to_char(to_date(TO_CHAR(disc.date_closed-interval '7' hour,'DD-MON-YYYY')||'00:00:00','DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS'), 'DD-MON-YYYY HH24:MI:SS')) as date_closed , disc.net_quantity , ( select opr2.quantity_completed from APPS.wip_operations opr2 where opr2.wip_entity_id = disc.wip_entity_id and opr2.operation_seq_num = (select max(opr.operation_seq_num) from APPS.wip_operations opr, APPS.wip_discrete_jobs disc2 where opr.wip_entity_id = disc2.wip_entity_id and disc2.wip_entity_id = disc.wip_entity_id))* agv.gx_cp_length * agv.gx_cp_th_weight as prod_qty_kgs ,gx_cp_alloy as alloy ,gx_cp_profile_id as profile -- Theoretical Order cost ,tbl0.TOT_THEORY_COST_RELIEVED -- Actual Order cost ,tbl0.TOT_ACTUAL_COST_INCURRED from XX.XXREPORT_Lzero_TBL tbl0 join APPS.oe_order_headers_all oeh on oeh.header_id = tbl0.header_id join APPS.oe_order_lines_all oel on oeh.org_id = oel.org_id and oeh.header_id = oel.header_id join APPS.wip_discrete_jobs disc on oel.line_id = disc.source_line_id join APPS.ego_gx_configured_pr_agv agv on agv.inventory_item_id= oel.inventory_item_id where oel.link_to_line_id is null )a ) xx;
几乎可以肯定没有任何简短的解决方案来调整此查询。这里的问题是它的大小和复杂性。表现不佳只是一个后果。
作为第一步,我会考虑从键盘上休息一下。拿起笔和纸,用通俗易懂的英语(或您喜欢的 "human" 语言)写下您希望通过此查询从数据库中得到回答的问题。然后问问自己 什么 columns/variables/attributes 你绝对需要回答这些问题? 也把它们写下来。
现在,您真的需要所有这些列、嵌套连接、选择等来生成这些变量吗?也许吧,但可能不是。这里的关键点是仅关注您需要的 data/information (YAGNI),然后从那里绘制出一张图片,您需要生成能够回答您问题的信息的基本关系。换句话说,由外而内,而不是相反。
我意识到这听起来可能有点抽象和模糊,但重点是保持清晰和简单的代码始终是一场持续的斗争。密切关注手头的 objective 将帮助您远离杂草。
最后说几点比较具体的想法,一目了然:
- 你真的需要那个工会吗?如果可以,尽量不要它。
- 嵌套很糟糕。嵌套嵌套特别糟糕。尽可能保持平整。
- 是否可以将其拆分为独立的、更小的查询?
- 为变量使用更具描述性的名称,明智地添加注释。
- 学习并掌握 SQL EXPLAIN 命令。