我们有3张桌子
TB_ETD_NON_MKTS_TRANS_OP - 3000万条记录
TB_ETD_NON_MKTS_POS_OP - 3000万条记录
TB_ETD_ENUMERATION - 包含100条记录的主表
我们正在执行以下查询以仅获取20条记录
SELECT * FROM ( SELECT
COUNT(*) OVER () CNT,
ROW_NUMBER() OVER (ORDER BY REPORTING_TIMESTAMP DESC NULLS LAST) RN,
INNER_QRY.* FROM
(SELECT MARRS_MSG_ID,
OWN_OR_DEL_REP,
ACTION,
UTI_VALUE UTI,
EN.DESCRIPTION REPORTING_PARTY,
OP.REPORTING_PARTY REPORTING_PARTY_CODE,
PRIMARY_ASSET_CLASS ASSET_CLASS,
TRADE_PARTY_INTR INTERNAL_TRADE_REF_ID,
TRANSACTION_REFERENCE_ID TRANSACTION_REFERENCE_ID,
NAME_OF_TRADE_PARTY_1 COUNTERPARTY_NAME,
ACTION INPUT_MESSAGE,
REPORTING_TIMESTAMP REPORTING_TIMESTAMP,
MSG_STATUS SDR_STATUS,
COLL_PORTFOLIO_CODE_PARTY_1 COLL_PORTFOLIO_CODE,
CORRECTION_STATUS CORRECTION_STATUS_CODE
FROM TB_ETD_NON_MKTS_TRANS_OP OP,
TB_ETD_ENUMERATION EN
WHERE OP.REPORTING_PARTY = EN.NAME
AND ( OWN_OR_DEL_REP NOT IN ('DD')
OR OWN_OR_DEL_REP IS NULL )
AND REPORTING_PARTY IN
(SELECT REGEXP_SUBSTR('HONGKONG,SINGAPORE,JERSEY','[^,]+', 1, LEVEL)
FROM DUAL
CONNECT BY REGEXP_SUBSTR('HONGKONG,SINGAPORE,JERSEY', '[^,]+', 1, LEVEL) IS NOT NULL
)
AND REPORTING_TIMESTAMP >= TO_DATE('11-JAN-2015','DD-MON-YYYY')
AND REPORTING_TIMESTAMP <= TO_DATE('14-JAN-2015','DD-MON-YYYY')
UNION ALL
SELECT MARRS_MSG_ID,
OWN_OR_DEL_REP,
ACTION,
UTI_VALUE UTI,
EN.DESCRIPTION REPORTING_PARTY,
OP.REPORTING_PARTY REPORTING_PARTY_CODE,
PRIMARY_ASSET_CLASS ASSET_CLASS,
TRADE_PARTY_INTR INTERNAL_TRADE_REF_ID,
TRANSACTION_REFERENCE_ID TRANSACTION_REFERENCE_ID,
NAME_OF_TRADE_PARTY_1 COUNTERPARTY_NAME,
LIFECYCLE_EVENT INPUT_MESSAGE,
REPORTING_TIMESTAMP REPORTING_TIMESTAMP,
MSG_STATUS SDR_STATUS,
COLL_PORTFOLIO_CODE_PARTY_1 COLL_PORTFOLIO_CODE,
CORRECTION_STATUS CORRECTION_STATUS_CODE
FROM TB_ETD_NON_MKTS_POS_OP OP,
TB_ETD_ENUMERATION EN
WHERE OP.REPORTING_PARTY = EN.NAME
AND ( OWN_OR_DEL_REP NOT IN ('DD')
OR OWN_OR_DEL_REP IS NULL )
AND REPORTING_PARTY IN
(SELECT REGEXP_SUBSTR('HONGKONG,SINGAPORE,JERSEY','[^,]+', 1, LEVEL)
FROM DUAL
CONNECT BY REGEXP_SUBSTR('HONGKONG,SINGAPORE,JERSEY', '[^,]+', 1, LEVEL) IS NOT NULL
)
AND REPORTING_TIMESTAMP >= TO_DATE('11-JAN-2015','DD-MON-YYYY')
AND REPORTING_TIMESTAMP <= TO_DATE('14-JAN-2015','DD-MON-YYYY')
) INNER_QRY ) WHERE RN >= '1' AND RN <= '20'
我们在REPORTING_TIMESTAMP上有索引
下面是执行计划,对我来说没问题,仍然只需要花费3分钟获取20条记录。
答案 0 :(得分:1)
以下是几个一般提示:
1)考虑重写这个表达式:
AND REPORTING_PARTY IN
(SELECT REGEXP_SUBSTR('HONGKONG,SINGAPORE,JERSEY','[^,]+', 1, LEVEL)
FROM DUAL
CONNECT BY REGEXP_SUBSTR('HONGKONG,SINGAPORE,JERSEY', '[^,]+', 1, LEVEL) IS NOT NULL
)
如下:
AND instr(','||:comma_separated_values||',', ','||REPORTING_PARTY||',') > 0
或在没有绑定的情况下:
AND instr(',HONGKONG,SINGAPORE,JERSEY,', ','||REPORTING_PARTY||',') > 0
2)考虑更换
OWN_OR_DEL_REP NOT IN ('DD')
OR OWN_OR_DEL_REP IS NULL
with:
NVL(OWN_OR_DEL_REP,'?') NOT IN ('DD')
3)尝试摆脱嵌套循环(使用提示use_hash
)