最近碰到了个问题,网上都找不到原因,望各位高手帮忙解释解释,谢谢了!
以下是存储过程的部分代码:CREATE OR REPLACE PROCEDURE SP_CMM_SELECT_FEES_QTY_VVL(V_CURSOR OUT SYS_REFCURSOR, --返回信息,
P_VESSEL_CODE IN SVL_VOYAGE_PLAN.VESSEL_CODE%TYPE,
P_VOYAGE_NO IN SVL_VOYAGE_PLAN.VOYAGE_NO%TYPE,
P_VOYAGE_LEG IN SVL_VOYAGE_PLAN.VOYAGE_LEG%TYPE,
P_BL_NO IN VARCHAR2,
P_BALANCE_UNITS IN VARCHAR2,
P_SAILLING_DATE_FROM IN VARCHAR2,
P_SAILLING_DATE_TO IN VARCHAR2,
P_VOYAGE_YEAR IN VARCHAR2,
P_VOYAGE_MONTH IN VARCHAR2,
P_ASSIGN_WEEK_FROM IN VARCHAR2,
P_ASSIGN_WEEK_TO IN VARCHAR2,
P_RP_FLAG IN VARCHAR2,
P_PORT_CODE IN VARCHAR2,
V_BK_FREIGHT_RECEIVE_IDS IN CLOB,
V_SOA_NO IN VARCHAR2, --SOA NO
V_CHARGE_CODE IN VARCHAR2,
V_CURRENCY IN VARCHAR2) ISBEGIN
IF (P_RP_FLAG = 'I') THEN
BEGIN
--应收
-- OPEN V_CURSOR FOR
DELETE FROM CMM_TEMP_AUTO_COUNT_COMMISSION;
INSERT INTO CMM_TEMP_AUTO_COUNT_COMMISSION C
(VESSEL_CODE, VOYAGE_NO, VOYAGE_LEG, ETD, RATE_LIST_ID)
(SELECT VVL.VESSEL_CODE,
VVL.VOYAGE_NO,
VVL.VOYAGE_LEG,
VVL.SAILLING_DATE,
WMSYS.WM_CONCAT(VVL.CURRENCY || ':' || VVL.AMOUNT) AS AMOUNT
FROM (SELECT BH.CURRENT_VESSEL_CODE VESSEL_CODE,
BH.CURRENT_VOYAGE_NO VOYAGE_NO,
BH.CURRENT_VOYAGE_LEG VOYAGE_LEG,
PORT.ETD SAILLING_DATE,
BF.CURRENCY,
SUM(BF.AMOUNT) AMOUNT
FROM DOC_BK_FREIGHT_RECEIVE BF,
VW_DOC_BOOKING_HEAD_OBM BH,
DOC_BK_ROUTING ROUTING,
SVL_VOYAGE_PLAN VP,
SVL_VOYAGE_PLAN_PORT PORT
WHERE BF.BOOKING_HEAD_ID = BH.BOOKING_HEAD_ID
AND BF.PAY_MODEL = 0
AND BH.SPLITE_COMBIN_VISIBLE_FLAG = 1
AND ......
AND (--TRIM(P_PORT_CODE) IS NULL OR
BH.CURRENT_PORT = P_PORT_CODE)
AND (--TRIM(P_PORT_CODE) IS NULL OR
BF.PORT_CODE = P_PORT_CODE)
AND BF.PAYER <> 'CNSHA_HQ'
......
GROUP BY BH.CURRENT_VESSEL_CODE,
BH.CURRENT_VOYAGE_NO,
BH.CURRENT_VOYAGE_LEG,
BF.CURRENCY,
PORT.ETD
) VVL
GROUP BY VVL.VESSEL_CODE,
VVL.VOYAGE_NO,
VVL.VOYAGE_LEG,
VVL.SAILLING_DATE);
OPEN V_CURSOR FOR
SELECT C.VESSEL_CODE,
C.VOYAGE_NO,
C.VOYAGE_LEG,
C.ETD AS SAILLING_DATE,
C.RATE_LIST_ID AS AMOUNT
FROM CMM_TEMP_AUTO_COUNT_COMMISSION C;
END;
END SP_CMM_SELECT_FEES_QTY_VVL;
这段代码中的AND (--TRIM(P_PORT_CODE) IS NULL OR
BH.CURRENT_PORT = P_PORT_CODE)
AND (--TRIM(P_PORT_CODE) IS NULL OR
BF.PORT_CODE = P_PORT_CODE)
把P_PORT_CODE为空的判断注释掉了,速度很快,之前这个是没有注释掉的,执行一次会卡到死机,请问大家为什么会这样?这个判断为空的语句对性能是因为什么造成了影响呢?说明下,这些表有的是上百万的。谢谢各位了!
以下是存储过程的部分代码:CREATE OR REPLACE PROCEDURE SP_CMM_SELECT_FEES_QTY_VVL(V_CURSOR OUT SYS_REFCURSOR, --返回信息,
P_VESSEL_CODE IN SVL_VOYAGE_PLAN.VESSEL_CODE%TYPE,
P_VOYAGE_NO IN SVL_VOYAGE_PLAN.VOYAGE_NO%TYPE,
P_VOYAGE_LEG IN SVL_VOYAGE_PLAN.VOYAGE_LEG%TYPE,
P_BL_NO IN VARCHAR2,
P_BALANCE_UNITS IN VARCHAR2,
P_SAILLING_DATE_FROM IN VARCHAR2,
P_SAILLING_DATE_TO IN VARCHAR2,
P_VOYAGE_YEAR IN VARCHAR2,
P_VOYAGE_MONTH IN VARCHAR2,
P_ASSIGN_WEEK_FROM IN VARCHAR2,
P_ASSIGN_WEEK_TO IN VARCHAR2,
P_RP_FLAG IN VARCHAR2,
P_PORT_CODE IN VARCHAR2,
V_BK_FREIGHT_RECEIVE_IDS IN CLOB,
V_SOA_NO IN VARCHAR2, --SOA NO
V_CHARGE_CODE IN VARCHAR2,
V_CURRENCY IN VARCHAR2) ISBEGIN
IF (P_RP_FLAG = 'I') THEN
BEGIN
--应收
-- OPEN V_CURSOR FOR
DELETE FROM CMM_TEMP_AUTO_COUNT_COMMISSION;
INSERT INTO CMM_TEMP_AUTO_COUNT_COMMISSION C
(VESSEL_CODE, VOYAGE_NO, VOYAGE_LEG, ETD, RATE_LIST_ID)
(SELECT VVL.VESSEL_CODE,
VVL.VOYAGE_NO,
VVL.VOYAGE_LEG,
VVL.SAILLING_DATE,
WMSYS.WM_CONCAT(VVL.CURRENCY || ':' || VVL.AMOUNT) AS AMOUNT
FROM (SELECT BH.CURRENT_VESSEL_CODE VESSEL_CODE,
BH.CURRENT_VOYAGE_NO VOYAGE_NO,
BH.CURRENT_VOYAGE_LEG VOYAGE_LEG,
PORT.ETD SAILLING_DATE,
BF.CURRENCY,
SUM(BF.AMOUNT) AMOUNT
FROM DOC_BK_FREIGHT_RECEIVE BF,
VW_DOC_BOOKING_HEAD_OBM BH,
DOC_BK_ROUTING ROUTING,
SVL_VOYAGE_PLAN VP,
SVL_VOYAGE_PLAN_PORT PORT
WHERE BF.BOOKING_HEAD_ID = BH.BOOKING_HEAD_ID
AND BF.PAY_MODEL = 0
AND BH.SPLITE_COMBIN_VISIBLE_FLAG = 1
AND ......
AND (--TRIM(P_PORT_CODE) IS NULL OR
BH.CURRENT_PORT = P_PORT_CODE)
AND (--TRIM(P_PORT_CODE) IS NULL OR
BF.PORT_CODE = P_PORT_CODE)
AND BF.PAYER <> 'CNSHA_HQ'
......
GROUP BY BH.CURRENT_VESSEL_CODE,
BH.CURRENT_VOYAGE_NO,
BH.CURRENT_VOYAGE_LEG,
BF.CURRENCY,
PORT.ETD
) VVL
GROUP BY VVL.VESSEL_CODE,
VVL.VOYAGE_NO,
VVL.VOYAGE_LEG,
VVL.SAILLING_DATE);
OPEN V_CURSOR FOR
SELECT C.VESSEL_CODE,
C.VOYAGE_NO,
C.VOYAGE_LEG,
C.ETD AS SAILLING_DATE,
C.RATE_LIST_ID AS AMOUNT
FROM CMM_TEMP_AUTO_COUNT_COMMISSION C;
END;
END SP_CMM_SELECT_FEES_QTY_VVL;
这段代码中的AND (--TRIM(P_PORT_CODE) IS NULL OR
BH.CURRENT_PORT = P_PORT_CODE)
AND (--TRIM(P_PORT_CODE) IS NULL OR
BF.PORT_CODE = P_PORT_CODE)
把P_PORT_CODE为空的判断注释掉了,速度很快,之前这个是没有注释掉的,执行一次会卡到死机,请问大家为什么会这样?这个判断为空的语句对性能是因为什么造成了影响呢?说明下,这些表有的是上百万的。谢谢各位了!
解决方案 »
- 如何将查出的没有返回结果的显示成null ,0这样的
- 请教oracle高手,帮忙完成!感激不尽
- 新手学习SQL 有疑问 请教
- 启动oracle数据库时出错
- ORACLE 8 中文乱码问题 急急急!
- 存储过程问题
- 请教一条简单的sql语句
- 简单问题:请教为什么sqlplus worksheet里查不到表?
- 我在保存一个表的数据时,有时无法保存,系统提示'ora-01041内部错误,hostdef扩展名不存在‘,这是为什么?
- 11G 有自动按周分区功能吗?
- 寻求帮助:oracle 10g用imp导入数据的时候报错:ORA-01658: 无法为表空间 MAXDATA 中的段创建 INITIAL 区
- 如何搬迁部分功能包和这些包相关对象到另一个库
我重新排版下,不然看得太乱了。
CREATE OR REPLACE PROCEDURE SP_CMM_SELECT_FEES_QTY_VVL
( V_CURSOR OUT SYS_REFCURSOR,
P_VESSEL_CODE IN SVL_VOYAGE_PLAN.VESSEL_CODE%TYPE,
P_VOYAGE_NO IN SVL_VOYAGE_PLAN.VOYAGE_NO%TYPE,
P_VOYAGE_LEG IN SVL_VOYAGE_PLAN.VOYAGE_LEG%TYPE,
P_BL_NO IN VARCHAR2,
......
P_PORT_CODE IN VARCHAR2,
......) ISBEGIN
BEGIN
DELETE FROM CMM_TEMP_AUTO_COUNT_COMMISSION;
INSERT INTO CMM_TEMP_AUTO_COUNT_COMMISSION C
(VESSEL_CODE, VOYAGE_NO, VOYAGE_LEG, ETD, RATE_LIST_ID)
(SELECT VVL.VESSEL_CODE,
VVL.VOYAGE_NO,
VVL.VOYAGE_LEG,
VVL.SAILLING_DATE,
WMSYS.WM_CONCAT(VVL.CURRENCY || ':' || VVL.AMOUNT) AS AMOUNT
FROM (SELECT BH.CURRENT_VESSEL_CODE VESSEL_CODE,
BH.CURRENT_VOYAGE_NO VOYAGE_NO,
BH.CURRENT_VOYAGE_LEG VOYAGE_LEG,
PORT.ETD SAILLING_DATE,
BF.CURRENCY,
SUM(BF.AMOUNT) AMOUNT
FROM DOC_BK_FREIGHT_RECEIVE BF,
VW_DOC_BOOKING_HEAD_OBM BH,
DOC_BK_ROUTING ROUTING,
SVL_VOYAGE_PLAN VP,
SVL_VOYAGE_PLAN_PORT PORT
WHERE BF.BOOKING_HEAD_ID = BH.BOOKING_HEAD_ID
AND BF.PAY_MODEL = 0
AND BH.SPLITE_COMBIN_VISIBLE_FLAG = 1
AND ......
AND (--TRIM(P_PORT_CODE) IS NULL OR
BH.CURRENT_PORT = P_PORT_CODE)
AND (--TRIM(P_PORT_CODE) IS NULL OR
BF.PORT_CODE = P_PORT_CODE)
AND BF.PAYER <> 'CNSHA_HQ'
......
GROUP BY BH.CURRENT_VESSEL_CODE,
BH.CURRENT_VOYAGE_NO,
BH.CURRENT_VOYAGE_LEG,
BF.CURRENCY,
PORT.ETD) VVL
GROUP BY VVL.VESSEL_CODE,
VVL.VOYAGE_NO,
VVL.VOYAGE_LEG,
VVL.SAILLING_DATE); OPEN V_CURSOR FOR
SELECT C.VESSEL_CODE,
C.VOYAGE_NO,
C.VOYAGE_LEG,
C.ETD AS SAILLING_DATE,
C.RATE_LIST_ID AS AMOUNT
FROM CMM_TEMP_AUTO_COUNT_COMMISSION C;
END;
END SP_CMM_SELECT_FEES_QTY_VVL;
1、给这一列加一个默认值:如9999, 不要让他为null
2、在这一列上加一个函数索引 nvl(列,9999)
3、把结果存到中间临时表,然后再过滤
那就是数据量较大,语句写的有问题了。
速度应该影响在,你传入空值的时候吧。
看看你主要sql的执行计划,优化下sql。
BH.CURRENT_PORT = P_PORT_CODE)
AND (--TRIM(P_PORT_CODE) IS NULL OR
BF.PORT_CODE = P_PORT_CODE)
用or时候看下执行计划,应该是不走索引了
explain plan for select ....(你的查询语句) ;
select * from table(dbms_xplan.display);