loop迴圈 長時間沒有返回結果

myownstars發表於2010-04-30
從昨天下午就收到公司前臺郵件 說某個pl/sql程式執行長時間沒有返回資料 以前卻沒有過類似的效能問題 而且該問題只在一個測試環境中存在 其他環境包括生產環境都很正常 先大致整理出該程式
CREATE OR REPLACE PROCEDURE get_cost
  (
   item_id_in              NUMBER,
   part_id_in           NUMBER,
   ship_method_in       NUMBER,
   region_in            NUMBER,
   price_out    OUT NUMBER,
   is_override_out         OUT VARCHAR2
  ) IS

  v_weight NUMBER(12,4);

BEGIN

   FOR c IN
    (
     SELECT mpo.ship_charge
       FROM ff_override mpo
      WHERE mpo.item_id            = item_id_in
        AND mpo.distributor_id     = partner_id_in
        AND mpo.shipping_method_no = ship_method_id_in
        AND mpo.region_id          = region_id_in
    ) LOOP

       price_out := c.ship_charge;
       is_override_out      := 'Y';

       RETURN;

   END LOOP;
END;
當debug該程式時候 幾個小時不會返回結果 但是在其他環境用不到1秒 ff_override表上有一個unique組合索引 正好是上述的四個欄位
另外 當用匿名程式執行時 同樣很快
DECLARE
item_fixed_price_out NUMBER;
is_override_out VARCHAR2(2);
BEGIN
dbms_output.put_line('123');
FOR c IN (
SELECT mpo.ship_charge
       FROM ff_override mpo
      WHERE mpo.item_id            = 13031529
        AND mpo.distributor_id     = 255075
        AND mpo.shipping_method_no = 101
        AND mpo.region_id          = 1001) LOOP
       dbms_output.put_line('456789');
       item_fixed_price_out := c.ship_charge;
       is_override_out      := 'Y';
       RETURN;
      END LOOP;
END;
--只耗時0.0031秒
如果在儲存過程中  去掉四個列中的任意一個 也就是
CREATE OR REPLACE PROCEDURE get_cost
  (
   item_id_in              NUMBER,
   part_id_in           NUMBER,
   ship_method_in       NUMBER,
   region_in            NUMBER,
   price_out    OUT NUMBER,
   is_override_out         OUT VARCHAR2
  ) IS

  v_weight NUMBER(12,4);

BEGIN

   FOR c IN
    (
     SELECT mpo.ship_charge
       FROM ff_override mpo
      WHERE mpo.item_id            = item_id_in
        AND mpo.distributor_id     = partner_id_in
        AND mpo.shipping_method_no = ship_method_id_in
        --AND mpo.region_id          = region_id_in
    ) LOOP

       price_out := c.ship_charge;
       is_override_out      := 'Y';

       RETURN;

   END LOOP;
END;
呼叫時也會很快的返回結果
現在所能肯定的是  
該表的索引完好  匿名過程呼叫時候返回超快 而且執行計劃用到了unique index
在儲存過程中 連線條件中任意三列組合 也能返回較快結果 但是四列組合卻超級慢
而且我們用的是客戶端 不能使用10046事件  動態效能檢視也少的可憐 只有v$session v$longops沒有v$session_wait
還請各位一道分析一下
PS: 諸如 飄過 頂 之類的垃圾回覆就不要了 大家都是出來混的 又這麼忙 彼此理解一下

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15480802/viewspace-688348/,如需轉載,請註明出處,否則將追究法律責任。

相關文章