从昨天下午就收到公司前台邮件 说某个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博客 ” ,链接:https://blog.itpub.net/15480802/viewspace-688348/
,如需转载,请注明出处,否则将追究法律责任。