我有一个子查询查询,大约需要10分钟的时间来执行,所以我想用JOIN编写相同的逻辑来更快地获得结果。但最终JOIN查询与子查询相比花费了更多的时间。
使用子查询
select count(distinct nrc_app_no) from nrc_doc_submit_tbl
where ng_status='Uploaded'
and (processed_by is null OR processed_by='XML1')
and nrc_app_no not in
(
select distinct nrc_app_no from nrc_doc_submit_tbl where ng_status='Parsed'
)
and
(
nrc_app_no not like '4%' and
nrc_app_no not like '5%' and
nrc_app_no not like '6%'
);
使用JOIN& SUBSTR
select count(distinct a.nrc_app_no)
from
nrc_doc_submit_tbl a left join nrc_doc_submit_tbl b
on
a.nrc_app_no=b.nrc_app_no and b.ng_status='Parsed' and a.ng_status='Uploaded'
and (a.processed_by is null OR a.processed_by='XML1')
where
b.nrc_app_no is null and substr(a.nrc_app_no,1,1) not in ('4','5','6');
数据库:Oracle 11g
表格大小:1000万行
我还附上了两个查询的计划。
主键:NRC_APP_NO,FAMILY_MEMBER_ID,NRC_DOC_SUBMIT_ID
答案 0 :(得分:0)
你可以通过改变它来加速第一个:
and nrc_app_no not in
(
select distinct nrc_app_no from nrc_doc_submit_tbl where ng_status='Parsed'
)
到此:
and nrc_app_no in
(
select nrc_app_no from nrc_doc_submit_tbl
minus
select nrc_app_no from nrc_doc_submit_tbl
where ng_status='Parsed'
)
not in
很慢。
对功能结果进行过滤也很慢。你有这个:
and substr(a.nrc_app_no,1,1) not in ('4','5','6')
使用第一个查询的语法可能会更好。
答案 1 :(得分:0)
您不需要使用自联接或相关子查询,因为您可以使用analytic function获得相同的功能(只需要一次表扫描):
elsif ($line =~ /^ID:\n/) { print $outputFile $line."|"; }
替代方案 - 不存在:
返回两个表(或索引)扫描:
SELECT COUNT( DISTINCT nrc_app_no )
FROM (
SELECT nrc_app_no,
ng_status,
processed_by,
COUNT( CASE ng_status WHEN 'Parsed' THEN 1 END )
OVER ( PARTITION BY nrc_app_no ) AS parsed_count
FROM nrc_doc_submit_tbl
)
WHERE ng_status = 'Uploaded'
AND (processed_by is null OR processed_by='XML1')
AND parsed_count = 0
AND nrc_app_no NOT LIKE '4%'
AND nrc_app_no NOT LIKE '5%'
AND nrc_app_no NOT LIKE '6%';