当我在以下条件下通过硬编码在查询下运行时,它可以快速运行:
... AND ooha.order_number BETWEEN NVL(5339914,ooha.order_number)
AND NVL(5339914,ooha.order_number)
但是当我将其作为参数使用时,它花费了将近2个小时以上的太多时间
... AND ooha.order_number BETWEEN NVL(:p,ooha.order_number)
AND NVL(:q,ooha.order_number)
以下是我的原始代码,请按照开发人员的观点尝试所有可能的解决方案:
SELECT ooha.order_number,
hps.addressee cus_name,
oola.line_number,
(SELECT rtrim(extract(xmlagg(xmlelement("a",set_name -- query to check ship_set
||'/')),'//text()'),',')
FROM oe_sets
WHERE header_id = ooha.header_id
AND set_type = 'SHIP_SET'
) ship_set,
msib.segment1 item_name,
ooha.booked_date,
oola.schedule_ship_date,
mp.ORGANIZATION_CODE,
oola.ordered_quantity,
oola.subinventory,
oola.project_id,
(SELECT description FROM fnd_user WHERE user_id = ooha.attribute12 -- query to check Customer Delivery Partner
) cdp,
(SELECT NVL(SUM(reservation_quantity),0) -- query to check Reservation Quantity
FROM mtl_reservations
WHERE demand_source_line_id = oola.line_id
) reserved_qty,
oola.header_id,
oola.line_id,
msib.inventory_item_id,
msib.organization_id,
msib.item_type,
msib.inventory_item_status_code,
cic.item_cost,
msib.ATTRIBUTE13
FROM oe_order_headers_all ooha,
oe_order_lines_all oola,
mtl_system_items_b msib,
hz_cust_site_uses_all csu ,
hz_cust_acct_sites_all cas ,
hz_party_sites hps,
mtl_parameters mp,
cst_item_costs cic
WHERE ooha.header_id = oola.header_id
AND oola.inventory_item_id = msib.inventory_item_id
AND oola.ship_to_org_id = csu.site_use_id
AND csu.cust_acct_site_id = cas.cust_acct_site_id
AND cas.party_site_id = hps.party_site_id
AND oola.ship_from_org_id = msib.ORGANIZATION_ID
AND msib.ORGANIZATION_ID = mp.ORGANIZATION_ID
AND cic.inventory_item_id = msib.inventory_item_id
AND cic.ORGANIZATION_ID = msib.ORGANIZATION_ID
and cic.COST_TYPE_ID=1
AND oola.SUBINVENTORY LIKE 'Direct'
AND oola.item_type_code IN ('CONFIG','STANDARD')
AND oola.project_id IS NOT NULL
AND OOLA.BOOKED_FLAG = 'Y'
AND OOLA.OPEN_FLAG = 'Y' AND oola.ship_from_org_id IN
(SELECT ood.organization_id
FROM org_organization_definitions ood
WHERE ood.operating_unit =
(SELECT operating_unit -- query to fetch operating unit
FROM org_organization_definitions ood1
WHERE ood1.organization_id = 2064
)
)
AND ooha.order_number BETWEEN NVL(5339914,ooha.order_number) AND NVL(5339914,ooha.order_number)
AND TRUNC(oola.schedule_ship_date) >= TRUNC(NVL(TO_DATE(null,'DD-MON-YYYY'),oola.schedule_ship_date))
AND TRUNC(oola.schedule_ship_date) <= TRUNC(NVL(TO_DATE(null,'DD-MON-YYYY'),oola.schedule_ship_date))
-光标选择查询结束
答案 0 :(得分:2)
... AND ooha.order_number在NVL(:p,ooha.order_number)之间 AND NVL(:q,ooha.order_number)
嗯,这是Oracle优化的首要任务。如果绑定变量都不为null并且覆盖合理范围,则使用嵌套循环的索引范围扫描可能是一个不错的计划。但是下一次调用可能会为:p和:q指定两个空值,在这种情况下,索引范围扫描/嵌套循环计划将是灾难性的。
Oracle的最新版本(从11g,iirc开始)具有绑定感知游标和绑定敏感游标的概念。如果您想阅读该功能,则称为自适应游标共享。
有了该功能,如果您足够运行此查询,Oracle应该抓住一个事实,即不同的绑定值需要不同的计划,这样最终您的性能会更好。使用/*+ BIND_AWARE */
提示可以帮助完成此过程。
老实说,我从来没有像我所希望的那样拥有这项功能。
如果需要,可以通过为优化器做一些工作来使其更轻松一些。即,将对ooha
的访问分为4部分:(a)都绑定不为null,(b)p为null,q不为null,(c)p不为null,q为空,并且(d)都绑定为null
例如:
select count(*)
from ( SELECT *
FROM oe_order_headers_all ooha
WHERE ooha.order_number between :p and :q
and :p is not null
and :q is not null
UNION ALL
select *
from oe_order_headers_all ooha
WHERE ooha.order_number >= :p
and :p is not null
and :q is null
UNION ALL
select *
from oe_order_headers_all ooha
WHERE ooha.order_number <= :q
and :p is null
and :q is not null
UNION ALL
select *
from oe_order_headers_all ooha
WHERE :p is null
and :q is null ) ooha;
不必这样做-不幸的是需要这样做。但是,可悲的是,有时它确实有帮助,我发现它比希望/等待自适应游标共享来拯救我更快,更可靠。