我创建了一个Oracle查询,稍后我需要在一个过程中进行集成。
在我的SQL块中,我有两个这样的嵌套循环(Select语句运行良好):
DECLARE
m_card_no NUMBER;
BEGIN
FOR i IN (SELECT DISTINCT VISA_NUMBER FROM LC.WEEKLY_ROP_CARD_A WHERE NOT EXISTS (SELECT 1 FROM LC.LCT_MOMP_ROP WHERE VISA_NO = VISA_NUMBER))
LOOP
FOR n IN (
SELECT DISTINCT l.new_clearance_no, l.occupation_code, l.sex_code, rtrim(ltrim(a.civil_number)) civil_number, a.name_e, a.name_a, a.date_of_birth, a.passport_number, a.passport_issue_country_code, a.passort_issue_date, a.passort_expiry_date, a.nationality_code, lpad(rtrim(ltrim(a.visa_number)),8,0) visa_number, a.visa_issue_date, a.visa_expiry_date, v.lct_occupation_clear_id, DECODE(V.LCM_VISA_APPL_TYPE_ID,7,'LOCAL ENDORSEMENT','ARRIVAL') TRAN
FROM WEEKLY_ROP_CARD_A A
JOIN LCT_OCCUPATION_CLEAR L ON L.OCCUPATION_CODE = A.OCCUPATION_CODE
JOIN LCT_APPL_VISA V ON V.LCT_OCCUPATION_CLEAR_ID = L.ID
where lpad(v.visa_no,8,0)=lpad(rtrim(ltrim(a.visa_number)),8,0) and v.lct_occupation_clear_id=l.id and a.last_mov_type='IN' AND ( LCM_VISA_APPL_TYPE_ID <> 6 or LCM_VISA_APPL_TYPE_ID is null) and lpad(v.visa_no,8,0)=i.VISA_NUMBER
)
LOOP
--INSERT QUERY TO ANOTHER TABLE HERE
END LOOP;
END LOOP;
END;
第一个FOR循环中的查询有160万条记录,第二个循环中有60万条记录。当我分别运行两个查询时,它提供结果,因此查询中没有任何错误。但是当我运行上面的代码块时,它甚至没有到达插入语句。有没有办法插入记录而没有任何问题?
答案 0 :(得分:1)
首先,基于一个集合的INSERT INTO ... SELECT FROM语句将比循环内的单行INSERT INTO ... VALUES语句快得多。
第二,嵌套循环比有效联接慢。因为您在外部循环中使用的表也在内部循环中,所以很容易消除两个循环。
将这些建议汇总在一起。...
insert into your_table
SELECT DISTINCT l.new_clearance_no,
l.occupation_code,
l.sex_code,
rtrim(ltrim(a.civil_number)) civil_number,
a.name_e,
a.name_a,
a.date_of_birth,
a.passport_number,
a.passport_issue_country_code,
a.passort_issue_date,
a.passort_expiry_date,
a.nationality_code,
lpad(rtrim(ltrim(a.visa_number)),8,0) visa_number,
a.visa_issue_date,
a.visa_expiry_date,
v.lct_occupation_clear_id,
DECODE(V.LCM_VISA_APPL_TYPE_ID,7,'LOCAL ENDORSEMENT','ARRIVAL') TRAN
FROM WEEKLY_ROP_CARD_A A
JOIN LCT_OCCUPATION_CLEAR L ON L.OCCUPATION_CODE = A.OCCUPATION_CODE
JOIN LCT_APPL_VISA V ON V.LCT_OCCUPATION_CLEAR_ID = L.ID
where lpad(v.visa_no,8,0)=lpad(rtrim(ltrim(a.visa_number)),8,0)
and v.lct_occupation_clear_id=l.id
and a.last_mov_type='IN'
AND ( LCM_VISA_APPL_TYPE_ID <> 6 or LCM_VISA_APPL_TYPE_ID is null)
and lpad(v.visa_no,8,0)=i.VISA_NUMBER
and NOT EXISTS (SELECT 1 FROM LC.LCT_MOMP_ROP WHERE VISA_NO = a.VISA_NUMBER)
;
此外,如果将LC.LCT_MOMP_ROP.VISA_NO 保证为not null
,则您可能想检查NOT IN是否比NOT EXISTS具有更高的性能。
答案 1 :(得分:0)
所有信用归功于APC的耐心重写。
如果花费的时间太长,您可以尝试使用以下版本,并查看执行计划中的等待内容和一些类似于以下内容的提示...并非所有冗长的查询都是因为dba:
-PQ_DISTRIBUTE(用于分区表)
-领先
-PRECOMPUTE_SUBQUERY(用于子查询)
-USE_HASH
-满
insert /*+ append parallel(aaa,8) */ into your_table aaa
SELECT /*+ parallel(A,4) parallel(L,4) parallel(V,4) */DISTINCT l.new_clearance_no,
l.occupation_code,
l.sex_code,
rtrim(ltrim(a.civil_number)) civil_number,
a.name_e,
a.name_a,
a.date_of_birth,
a.passport_number,
a.passport_issue_country_code,
a.passort_issue_date,
a.passort_expiry_date,
a.nationality_code,
lpad(rtrim(ltrim(a.visa_number)),8,0) visa_number,
a.visa_issue_date,
a.visa_expiry_date,
v.lct_occupation_clear_id,
DECODE(V.LCM_VISA_APPL_TYPE_ID,7,'LOCAL ENDORSEMENT','ARRIVAL') TRAN
FROM WEEKLY_ROP_CARD_A A
JOIN LCT_OCCUPATION_CLEAR L ON L.OCCUPATION_CODE = A.OCCUPATION_CODE
JOIN LCT_APPL_VISA V ON V.LCT_OCCUPATION_CLEAR_ID = L.ID
where lpad(v.visa_no,8,0)=lpad(rtrim(ltrim(a.visa_number)),8,0)
and v.lct_occupation_clear_id=l.id
and a.last_mov_type='IN'
AND ( LCM_VISA_APPL_TYPE_ID <> 6 or LCM_VISA_APPL_TYPE_ID is null)
and lpad(v.visa_no,8,0)=i.VISA_NUMBER
and NOT EXISTS (SELECT 1 FROM LC.LCT_MOMP_ROP WHERE VISA_NO = a.VISA_NUMBER)