简体   繁体   English

通过使用变量作为参数,选择查询花费了太多时间

[英]Select query is taking too much time by using variable as parameter

When I am running below query by hardcoded in where condition it runs fast: 当我在条件下通过硬编码在查询下面运行时,它运行很快:

... AND ooha.order_number BETWEEN NVL(5339914,ooha.order_number) 
    AND NVL(5339914,ooha.order_number)

But when I taking it in a parameter it is taking too much time almost more than 2 hours 但是,当我将其作为参数使用时,它花费了将近2个小时以上的太多时间

... AND ooha.order_number BETWEEN NVL(:p,ooha.order_number) 
    AND NVL(:q,ooha.order_number)

below is my original code please look into this as I tried all possible solution as per developer point of view: 以下是我的原始代码,请按照开发人员的观点尝试所有可能的解决方案:

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))

-- end of cursor select query -游标选择查询结束

... AND ooha.order_number BETWEEN NVL(:p,ooha.order_number) AND NVL(:q,ooha.order_number) ... AND ooha.order_number在NVL(:p,ooha.order_number)和NVL(:q,ooha.order_number)之间

Well, that's a tall order for Oracle to optimize. 好吧,这是Oracle优化的首要任务。 If the bind variables are both non-null and cover a reasonable range, an index range scan with nested loops is probably a good plan. 如果绑定变量都不为null并且覆盖合理范围,则使用嵌套循环的索引范围扫描可能是一个不错的计划。 But the next call might specify two null values for :p and :q, in which case the index range scan / nested loop plan would be disastrous. 但是下一次调用可能会为:p和:q指定两个空值,在这种情况下,索引范围扫描/嵌套循环计划将是灾难性的。

Recent versions of Oracle (starting with 11g, iirc) have the concept of bind-aware and bind-sensitive cursors. Oracle的最新版本(从11g,iirc开始)具有绑定感知和绑定敏感游标的概念。 The feature is called adaptive cursor sharing, if you want to read up on it. 如果您想阅读该功能,则称为自适应游标共享。
With that feature, if you run this query enough, Oracle should catch on to the fact that different bind values require different plans so that, eventually, your performance becomes better. 有了该功能,如果您足够运行此查询,Oracle应该抓住一个事实,即不同的绑定值需要不同的计划,这样最终您的性能会更好。 Using the /*+ BIND_AWARE */ hint may help this process along. 使用/*+ BIND_AWARE */提示可能有助于完成此过程。

Honestly, I've never had as much luck with the feature as I would like. 老实说,我从来没有像我所希望的那样拥有这项功能。

If you want, you can help make the optimizer's life a little easier by doing some of its work for it. 如果需要,可以通过执行一些优化工作来使它更轻松一些。 Namely, split your access of ooha into 4 parts: (a) both binds not null, (b) p null, q not null, (c) p not null, q null, and (d) both binds null. 即, ooha的访问分为四个部分:(a)都绑定不为null,(b)p为null,q不为null,(c)p不为null,q为空,并且(d)都绑定为null。

For example: 例如:

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;

It shouldn't be necessary to do this -- and it's unfortunate to need to do it. 不必这样做-不幸的是需要这样做。 But, sadly, sometimes it does help and I find that it can be faster and more reliable than hoping/waiting for adaptive cursor sharing to save me. 但是,令人遗憾的是,有时它确实有帮助,我发现它比希望/等待自适应游标共享来拯救我更快,更可靠。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM