昨天刚写了半连接改写系列,今天就遇到了此类型SQL:

优化前

耗时:28s

返回:0

SELECT D.DAILYAUDITNO, D.TRANSTOACC
FROM PB_DOIC.MM_DAILYREPORT_TD D
WHERE D.REPORTSTATUS = '4'
AND D.TRANSTOACC IN ('00', 'B1')
AND EXISTS (SELECT 1
FROM PB_DOIC.MM_DAILYREPORT_DETAIL_TD
WHERE DAILYAUDITNO = D.DAILYAUDITNO
AND BUSINESSONE || BUSINESSTWO NOT IN
('604988', '605988', '606988', '607988')
AND BUSINESSTWO != '991')
AND NOT EXISTS
(SELECT 1
FROM PB_DOIC.MM_DAILYREPORT_DETAIL_TD E
WHERE E.DAILYAUDITNO = D.DAILYAUDITNO
AND E.BUSINESSONE || E.BUSINESSTWO NOT IN
('604988', '605988', '606988', '607988')
AND E.BUSINESSTWO != '991'
AND NOT EXISTS
(SELECT 1
FROM PB_DOIC.MM_VOUCHERMODULE_TC V
WHERE V.BUSINESSTYPE = E.BUSINESSONE || E.BUSINESSTWO
AND V.MODULETYPE = '1'
AND V.MODULESTATUS = 0))
FOR UPDATE OF D.TRANSTOACC NOWAIT Execution Plan
----------------------------------------------------------
Plan hash value: 915590932 --------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10 | 1160 | 20991 (2)| 00:04:12 |
| 1 | FOR UPDATE | | | | | |
| 2 | NESTED LOOPS | | 1 | 116 | 20945 (2)| 00:04:12 |
| 3 | SORT UNIQUE | | 29 | 1943 | 20928 (2)| 00:04:12 |
|* 4 | INDEX FAST FULL SCAN | IDX_MM_DAILYREPORT_DETAIL_TD | 29 | 1943 | 20928 (2)| 00:04:12 |
|* 5 | TABLE ACCESS BY INDEX ROWID| MM_DAILYREPORT_TD | 1 | 49 | 2 (0)| 00:00:01 |
|* 6 | INDEX UNIQUE SCAN | PK_MM_DAILYREPORT_TD | 1 | | 1 (0)| 00:00:01 |
|* 7 | INDEX RANGE SCAN | IDX_MM_DAILYREPORT_DETAIL_TD | 1 | 67 | 7 (0)| 00:00:01 |
|* 8 | INDEX RANGE SCAN | PK_MM_VOUCHERMODULE_TC | 1 | 15 | 2 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 4 - filter("BUSINESSONE"||"BUSINESSTWO"<>'604988' AND "BUSINESSONE"||"BUSINESSTWO"<>'605988' AND
"BUSINESSONE"||"BUSINESSTWO"<>'606988' AND "BUSINESSONE"||"BUSINESSTWO"<>'607988' AND
"BUSINESSTWO"<>'991')
5 - filter(("D"."TRANSTOACC"='00' OR "D"."TRANSTOACC"='B1') AND "D"."REPORTSTATUS"='4')
6 - access("DAILYAUDITNO"="D"."DAILYAUDITNO")
filter( NOT EXISTS (SELECT /*+ */ 0 FROM "PB_DOIC"."MM_DAILYREPORT_DETAIL_TD" "SYS_ALIAS_2"
WHERE "E"."DAILYAUDITNO"=:B1 AND "E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'604988' AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'605988' AND "E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'606988' AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'607988' AND "E"."BUSINESSTWO"<>'991' AND NOT EXISTS (SELECT
/*+ */ 0 FROM "PB_DOIC"."MM_VOUCHERMODULE_TC" "V" WHERE "V"."BUSINESSTYPE"=:B2||:B3 AND
"V"."MODULETYPE"='1' AND "V"."MODULESTATUS"=0)))
7 - access("E"."DAILYAUDITNO"=:B1)
filter("E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'604988' AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'605988' AND "E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'606988' AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'607988' AND "E"."BUSINESSTWO"<>'991' AND NOT EXISTS (SELECT
/*+ */ 0 FROM "PB_DOIC"."MM_VOUCHERMODULE_TC" "V" WHERE "V"."BUSINESSTYPE"=:B1||:B2 AND
"V"."MODULETYPE"='1' AND "V"."MODULESTATUS"=0))
8 - access("V"."MODULETYPE"='1' AND "V"."BUSINESSTYPE"=:B1||:B2 AND "V"."MODULESTATUS"=0)
filter("V"."MODULESTATUS"=0) Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
3809828 consistent gets
347 physical reads
0 redo size
397 bytes sent via SQL*Net to client
481 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
0 rows processed

分析

查看执行计划,发现ID=3处为 SORT UNIQUE ,而SQL语句并没有DISTINCT关键字,难道SQL进行自动改写了?

为了确认自己想法,我进行以下手动改写,把半连接手动改写成内连接:

改写之前,先确认表与表之间的关系:

select count(*),count(distinct DAILYAUDITNO) from MM_DAILYREPORT_DETAIL_TD;

COUNT(*)    COUNT(DISTINCTDAILYAUDITNO)
-------- -----------------------
5111081 441898 select count(*),count(distinct DAILYAUDITNO) from MM_DAILYREPORT_TD; COUNT(*) COUNT(DISTINCTDAILYAUDITNO)
-------- -----------------------
441940 441940 --表MM_DAILYREPORT_TD与表MM_DAILYREPORT_DETAIL_TD是1:N的关系,所以改写时候,需要先去重,再连接。 SELECT D.DAILYAUDITNO, D.TRANSTOACC
FROM PB_DOIC.MM_DAILYREPORT_TD D
INNER JOIN (SELECT DISTINCT DAILYAUDITNO
FROM PB_DOIC.MM_DAILYREPORT_DETAIL_TD
WHERE BUSINESSONE || BUSINESSTWO NOT IN
('604988', '605988', '606988', '607988')
AND BUSINESSTWO != '991') TD
ON D.DAILYAUDITNO = TD.DAILYAUDITNO
WHERE D.REPORTSTATUS = '4'
AND D.TRANSTOACC IN ('00', 'B1')
AND NOT EXISTS
(SELECT 1
FROM PB_DOIC.MM_DAILYREPORT_DETAIL_TD E
WHERE E.DAILYAUDITNO = D.DAILYAUDITNO
AND E.BUSINESSONE || E.BUSINESSTWO NOT IN
('604988', '605988', '606988', '607988')
AND E.BUSINESSTWO != '991'
AND NOT EXISTS
(SELECT 1
FROM PB_DOIC.MM_VOUCHERMODULE_TC V
WHERE V.BUSINESSTYPE = E.BUSINESSONE || E.BUSINESSTWO
AND V.MODULETYPE = '1'
AND V.MODULESTATUS = 0))
FOR UPDATE OF D.TRANSTOACC NOWAIT; Execution Plan
----------------------------------------------------------
Plan hash value: 1310135718 --------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 25 | 2250 | 21076 (2)| 00:04:13 |
| 1 | FOR UPDATE | | | | | |
| 2 | NESTED LOOPS | | 1 | 90 | 20959 (2)| 00:04:12 |
| 3 | VIEW | | 29 | 1189 | 20929 (2)| 00:04:12 |
| 4 | SORT UNIQUE | | 29 | 1943 | 20929 (2)| 00:04:12 |
|* 5 | INDEX FAST FULL SCAN | IDX_MM_DAILYREPORT_DETAIL_TD | 29 | 1943 | 20928 (2)| 00:04:12 |
|* 6 | TABLE ACCESS BY INDEX ROWID| MM_DAILYREPORT_TD | 1 | 49 | 2 (0)| 00:00:01 |
|* 7 | INDEX UNIQUE SCAN | PK_MM_DAILYREPORT_TD | 1 | | 1 (0)| 00:00:01 |
|* 8 | INDEX RANGE SCAN | IDX_MM_DAILYREPORT_DETAIL_TD | 1 | 67 | 7 (0)| 00:00:01 |
|* 9 | INDEX RANGE SCAN | PK_MM_VOUCHERMODULE_TC | 1 | 15 | 2 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 5 - filter("BUSINESSONE"||"BUSINESSTWO"<>'604988' AND "BUSINESSONE"||"BUSINESSTWO"<>'605988' AND
"BUSINESSONE"||"BUSINESSTWO"<>'606988' AND "BUSINESSONE"||"BUSINESSTWO"<>'607988' AND
"BUSINESSTWO"<>'991')
6 - filter(("D"."TRANSTOACC"='00' OR "D"."TRANSTOACC"='B1') AND "D"."REPORTSTATUS"='4')
7 - access("D"."DAILYAUDITNO"="TD"."DAILYAUDITNO")
filter( NOT EXISTS (SELECT /*+ */ 0 FROM "PB_DOIC"."MM_DAILYREPORT_DETAIL_TD" "SYS_ALIAS_2"
WHERE "E"."DAILYAUDITNO"=:B1 AND "E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'604988' AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'605988' AND "E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'606988' AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'607988' AND "E"."BUSINESSTWO"<>'991' AND NOT EXISTS (SELECT
/*+ */ 0 FROM "PB_DOIC"."MM_VOUCHERMODULE_TC" "V" WHERE "V"."BUSINESSTYPE"=:B2||:B3 AND
"V"."MODULETYPE"='1' AND "V"."MODULESTATUS"=0)))
8 - access("E"."DAILYAUDITNO"=:B1)
filter("E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'604988' AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'605988' AND "E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'606988' AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'607988' AND "E"."BUSINESSTWO"<>'991' AND NOT EXISTS (SELECT
/*+ */ 0 FROM "PB_DOIC"."MM_VOUCHERMODULE_TC" "V" WHERE "V"."BUSINESSTYPE"=:B1||:B2 AND
"V"."MODULETYPE"='1' AND "V"."MODULESTATUS"=0))
9 - access("V"."MODULETYPE"='1' AND "V"."BUSINESSTYPE"=:B1||:B2 AND "V"."MODULESTATUS"=0)
filter("V"."MODULESTATUS"=0) Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
3809828 consistent gets
431 physical reads
0 redo size
397 bytes sent via SQL*Net to client
481 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
1 sorts (memory)
0 sorts (disk)
0 rows processed

可以看出改写后的执行计划于改写之前执行计划基本一致,所以可以确定SQL是进行自动改写内连接而导致的性能问题。

优化方法1:

耗时:0.4s

返回:0

--在半连接里加上ROWNUM>0,让SQL不进行展开。
SELECT D.DAILYAUDITNO, D.TRANSTOACC
FROM PB_DOIC.MM_DAILYREPORT_TD D
WHERE D.REPORTSTATUS = '4'
AND D.TRANSTOACC IN ('00', 'B1')
AND EXISTS (SELECT 1
FROM PB_DOIC.MM_DAILYREPORT_DETAIL_TD
WHERE DAILYAUDITNO = D.DAILYAUDITNO
AND BUSINESSONE || BUSINESSTWO NOT IN
('604988', '605988', '606988', '607988')
AND BUSINESSTWO != '991' AND ROWNUM>0)
AND NOT EXISTS
(SELECT 1
FROM PB_DOIC.MM_DAILYREPORT_DETAIL_TD E
WHERE E.DAILYAUDITNO = D.DAILYAUDITNO
AND E.BUSINESSONE || E.BUSINESSTWO NOT IN
('604988', '605988', '606988', '607988')
AND E.BUSINESSTWO != '991'
AND NOT EXISTS
(SELECT 1
FROM PB_DOIC.MM_VOUCHERMODULE_TC V
WHERE V.BUSINESSTYPE = E.BUSINESSONE || E.BUSINESSTWO
AND V.MODULETYPE = '1'
AND V.MODULESTATUS = 0))
FOR UPDATE OF D.TRANSTOACC NOWAIT; Execution Plan
----------------------------------------------------------
Plan hash value: 4088075167 ------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 49 | 336K (1)| 01:07:15 |
| 1 | FOR UPDATE | | | | | |
|* 2 | FILTER | | | | | |
|* 3 | TABLE ACCESS FULL | MM_DAILYREPORT_TD | 22372 | 1070K| 2632 (2)| 00:00:32 |
| 4 | COUNT | | | | | |
|* 5 | FILTER | | | | | |
|* 6 | INDEX RANGE SCAN | IDX_MM_DAILYREPORT_DETAIL_TD | 1 | 67 | 7 (0)| 00:00:01 |
|* 7 | INDEX RANGE SCAN | IDX_MM_DAILYREPORT_DETAIL_TD | 1 | 67 | 7 (0)| 00:00:01 |
|* 8 | INDEX RANGE SCAN| PK_MM_VOUCHERMODULE_TC | 1 | 15 | 2 (0)| 00:00:01 |
------------------------------------------------------------------------------------------------------ Predicate Information (identified by operation id):
--------------------------------------------------- 2 - filter( EXISTS (SELECT /*+ */ 0 FROM "PB_DOIC"."MM_DAILYREPORT_DETAIL_TD"
"MM_DAILYREPORT_DETAIL_TD" WHERE ROWNUM>0 AND "DAILYAUDITNO"=:B1 AND
"BUSINESSONE"||"BUSINESSTWO"<>'604988' AND "BUSINESSONE"||"BUSINESSTWO"<>'605988' AND
"BUSINESSONE"||"BUSINESSTWO"<>'606988' AND "BUSINESSONE"||"BUSINESSTWO"<>'607988' AND
"BUSINESSTWO"<>'991') AND NOT EXISTS (SELECT /*+ */ 0 FROM
"PB_DOIC"."MM_DAILYREPORT_DETAIL_TD" "SYS_ALIAS_2" WHERE "E"."DAILYAUDITNO"=:B2 AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'604988' AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'605988' AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'606988' AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'607988' AND "E"."BUSINESSTWO"<>'991' AND NOT EXISTS
(SELECT /*+ */ 0 FROM "PB_DOIC"."MM_VOUCHERMODULE_TC" "V" WHERE "V"."BUSINESSTYPE"=:B3||:B4
AND "V"."MODULETYPE"='1' AND "V"."MODULESTATUS"=0)))
3 - filter(("D"."TRANSTOACC"='00' OR "D"."TRANSTOACC"='B1') AND "D"."REPORTSTATUS"='4')
5 - filter(ROWNUM>0)
6 - access("DAILYAUDITNO"=:B1)
filter("BUSINESSONE"||"BUSINESSTWO"<>'604988' AND
"BUSINESSONE"||"BUSINESSTWO"<>'605988' AND "BUSINESSONE"||"BUSINESSTWO"<>'606988' AND
"BUSINESSONE"||"BUSINESSTWO"<>'607988' AND "BUSINESSTWO"<>'991')
7 - access("E"."DAILYAUDITNO"=:B1)
filter("E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'604988' AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'605988' AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'606988' AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'607988' AND "E"."BUSINESSTWO"<>'991' AND NOT EXISTS
(SELECT /*+ */ 0 FROM "PB_DOIC"."MM_VOUCHERMODULE_TC" "V" WHERE "V"."BUSINESSTYPE"=:B1||:B2
AND "V"."MODULETYPE"='1' AND "V"."MODULESTATUS"=0))
8 - access("V"."MODULETYPE"='1' AND "V"."BUSINESSTYPE"=:B1||:B2 AND "V"."MODULESTATUS"=0)
filter("V"."MODULESTATUS"=0) Statistics
----------------------------------------------------------
0 recursive calls
0 db block gets
105048 consistent gets
0 physical reads
0 redo size
397 bytes sent via SQL*Net to client
481 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
0 rows processed

优化方法2:

耗时:0.4s

返回:0

--添加hint: /*+ no_unnest */ 目的也是让半连接的sql不展开。与上面改写效果一致。

SELECT D.DAILYAUDITNO, D.TRANSTOACC
FROM PB_DOIC.MM_DAILYREPORT_TD D
WHERE D.REPORTSTATUS = '4'
AND D.TRANSTOACC IN ('00', 'B1')
AND EXISTS (SELECT /*+NO_UNNEST*/1
FROM PB_DOIC.MM_DAILYREPORT_DETAIL_TD
WHERE DAILYAUDITNO = D.DAILYAUDITNO
AND BUSINESSONE || BUSINESSTWO NOT IN
('604988', '605988', '606988', '607988')
AND BUSINESSTWO != '991')
AND NOT EXISTS
(SELECT 1
FROM PB_DOIC.MM_DAILYREPORT_DETAIL_TD E
WHERE E.DAILYAUDITNO = D.DAILYAUDITNO
AND E.BUSINESSONE || E.BUSINESSTWO NOT IN
('604988', '605988', '606988', '607988')
AND E.BUSINESSTWO != '991'
AND NOT EXISTS
(SELECT 1
FROM PB_DOIC.MM_VOUCHERMODULE_TC V
WHERE V.BUSINESSTYPE = E.BUSINESSONE || E.BUSINESSTWO
AND V.MODULETYPE = '1'
AND V.MODULESTATUS = 0))
FOR UPDATE OF D.TRANSTOACC NOWAIT Execution Plan
----------------------------------------------------------
Plan hash value: 991259826 -----------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 49 | 336K (1)| 01:07:15 |
| 1 | FOR UPDATE | | | | | |
|* 2 | FILTER | | | | | |
|* 3 | TABLE ACCESS FULL | MM_DAILYREPORT_TD | 22372 | 1070K| 2632 (2)| 00:00:32 |
|* 4 | INDEX RANGE SCAN | IDX_MM_DAILYREPORT_DETAIL_TD | 1 | 67 | 7 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | IDX_MM_DAILYREPORT_DETAIL_TD | 1 | 67 | 7 (0)| 00:00:01 |
|* 6 | INDEX RANGE SCAN| PK_MM_VOUCHERMODULE_TC | 1 | 15 | 2 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 2 - filter( EXISTS (SELECT /*+ NO_UNNEST */ 0 FROM "PB_DOIC"."MM_DAILYREPORT_DETAIL_TD"
"MM_DAILYREPORT_DETAIL_TD" WHERE "DAILYAUDITNO"=:B1 AND
"BUSINESSONE"||"BUSINESSTWO"<>'604988' AND "BUSINESSONE"||"BUSINESSTWO"<>'605988' AND
"BUSINESSONE"||"BUSINESSTWO"<>'606988' AND "BUSINESSONE"||"BUSINESSTWO"<>'607988' AND
"BUSINESSTWO"<>'991') AND NOT EXISTS (SELECT /*+ */ 0 FROM
"PB_DOIC"."MM_DAILYREPORT_DETAIL_TD" "SYS_ALIAS_2" WHERE "E"."DAILYAUDITNO"=:B2 AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'604988' AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'605988' AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'606988' AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'607988' AND "E"."BUSINESSTWO"<>'991' AND NOT EXISTS
(SELECT /*+ */ 0 FROM "PB_DOIC"."MM_VOUCHERMODULE_TC" "V" WHERE "V"."BUSINESSTYPE"=:B3||:B4
AND "V"."MODULETYPE"='1' AND "V"."MODULESTATUS"=0)))
3 - filter(("D"."TRANSTOACC"='00' OR "D"."TRANSTOACC"='B1') AND "D"."REPORTSTATUS"='4')
4 - access("DAILYAUDITNO"=:B1)
filter("BUSINESSONE"||"BUSINESSTWO"<>'604988' AND
"BUSINESSONE"||"BUSINESSTWO"<>'605988' AND "BUSINESSONE"||"BUSINESSTWO"<>'606988' AND
"BUSINESSONE"||"BUSINESSTWO"<>'607988' AND "BUSINESSTWO"<>'991')
5 - access("E"."DAILYAUDITNO"=:B1)
filter("E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'604988' AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'605988' AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'606988' AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'607988' AND "E"."BUSINESSTWO"<>'991' AND NOT EXISTS
(SELECT /*+ */ 0 FROM "PB_DOIC"."MM_VOUCHERMODULE_TC" "V" WHERE "V"."BUSINESSTYPE"=:B1||:B2
AND "V"."MODULETYPE"='1' AND "V"."MODULESTATUS"=0))
6 - access("V"."MODULETYPE"='1' AND "V"."BUSINESSTYPE"=:B1||:B2 AND "V"."MODULESTATUS"=0)
filter("V"."MODULESTATUS"=0) Statistics
----------------------------------------------------------
1 recursive calls
0 db block gets
105048 consistent gets
0 physical reads
0 redo size
397 bytes sent via SQL*Net to client
481 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
0 sorts (memory)
0 sorts (disk)
0 rows processed

优化方法3:

耗时:0.4s

返回:0

添加hint:/*+ nl_sj */,目的让SQL走semi join

SELECT D.DAILYAUDITNO, D.TRANSTOACC
FROM PB_DOIC.MM_DAILYREPORT_TD D
WHERE D.REPORTSTATUS = '4'
AND D.TRANSTOACC IN ('00', 'B1')
AND EXISTS (SELECT /*+nl_sj*/ 1
FROM PB_DOIC.MM_DAILYREPORT_DETAIL_TD
WHERE DAILYAUDITNO = D.DAILYAUDITNO
AND BUSINESSONE || BUSINESSTWO NOT IN
('604988', '605988', '606988', '607988')
AND BUSINESSTWO != '991')
AND NOT EXISTS
(SELECT 1
FROM PB_DOIC.MM_DAILYREPORT_DETAIL_TD E
WHERE E.DAILYAUDITNO = D.DAILYAUDITNO
AND E.BUSINESSONE || E.BUSINESSTWO NOT IN
('604988', '605988', '606988', '607988')
AND E.BUSINESSTWO != '991'
AND NOT EXISTS
(SELECT 1
FROM PB_DOIC.MM_VOUCHERMODULE_TC V
WHERE V.BUSINESSTYPE = E.BUSINESSONE || E.BUSINESSTWO
AND V.MODULETYPE = '1'
AND V.MODULESTATUS = 0))
FOR UPDATE OF D.TRANSTOACC NOWAIT Execution Plan
----------------------------------------------------------
Plan hash value: 2686500646 -----------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 34 | 3944 | 137K (1)| 00:27:29 |
| 1 | FOR UPDATE | | | | | |
|* 2 | FILTER | | | | | |
| 3 | NESTED LOOPS SEMI | | 34 | 3944 | 137K (1)| 00:27:27 |
|* 4 | TABLE ACCESS FULL| MM_DAILYREPORT_TD | 22372 | 1070K| 2632 (2)| 00:00:32 |
|* 5 | INDEX RANGE SCAN | IDX_MM_DAILYREPORT_DETAIL_TD | 1 | 67 | 6 (0)| 00:00:01 |
|* 6 | INDEX RANGE SCAN | IDX_MM_DAILYREPORT_DETAIL_TD | 1 | 67 | 7 (0)| 00:00:01 |
|* 7 | INDEX RANGE SCAN | PK_MM_VOUCHERMODULE_TC | 1 | 15 | 2 (0)| 00:00:01 |
----------------------------------------------------------------------------------------------------- Predicate Information (identified by operation id):
--------------------------------------------------- 2 - filter( NOT EXISTS (SELECT /*+ */ 0 FROM "PB_DOIC"."MM_DAILYREPORT_DETAIL_TD"
"SYS_ALIAS_2" WHERE "E"."DAILYAUDITNO"=:B1 AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'604988' AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'605988' AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'606988' AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'607988' AND "E"."BUSINESSTWO"<>'991' AND NOT EXISTS
(SELECT /*+ */ 0 FROM "PB_DOIC"."MM_VOUCHERMODULE_TC" "V" WHERE "V"."BUSINESSTYPE"=:B2||:B3
AND "V"."MODULETYPE"='1' AND "V"."MODULESTATUS"=0)))
4 - filter(("D"."TRANSTOACC"='00' OR "D"."TRANSTOACC"='B1') AND "D"."REPORTSTATUS"='4')
5 - access("DAILYAUDITNO"="D"."DAILYAUDITNO")
filter("BUSINESSONE"||"BUSINESSTWO"<>'604988' AND
"BUSINESSONE"||"BUSINESSTWO"<>'605988' AND "BUSINESSONE"||"BUSINESSTWO"<>'606988' AND
"BUSINESSONE"||"BUSINESSTWO"<>'607988' AND "BUSINESSTWO"<>'991')
6 - access("E"."DAILYAUDITNO"=:B1)
filter("E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'604988' AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'605988' AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'606988' AND
"E"."BUSINESSONE"||"E"."BUSINESSTWO"<>'607988' AND "E"."BUSINESSTWO"<>'991' AND NOT EXISTS
(SELECT /*+ */ 0 FROM "PB_DOIC"."MM_VOUCHERMODULE_TC" "V" WHERE "V"."BUSINESSTYPE"=:B1||:B2
AND "V"."MODULETYPE"='1' AND "V"."MODULESTATUS"=0))
7 - access("V"."MODULETYPE"='1' AND "V"."BUSINESSTYPE"=:B1||:B2 AND "V"."MODULESTATUS"=0)
filter("V"."MODULESTATUS"=0) Statistics
----------------------------------------------------------
2114 recursive calls
0 db block gets
83115 consistent gets
1341 physical reads
0 redo size
397 bytes sent via SQL*Net to client
481 bytes received via SQL*Net from client
1 SQL*Net roundtrips to/from client
77 sorts (memory)
0 sorts (disk)
0 rows processed

处理半连接SQL自动改写内连接SQL一例的更多相关文章

  1. Sql server中内连接语句

    数据库中学生表和课程表如下: 内连接sql语句: select a.studentName,a.studentAge,b.courseName from student a inner join co ...

  2. SQL Server中内连接和外连接的区别

    SQL Server中内连接和外连接的区别 假设一个数据库中有两张表,一张是学生表StudentInfo,一张是班级表ClassInfo,两张表之间用ClassId字段进行关联. 如果用内连接,正常的 ...

  3. 你真的会玩SQL吗?内连接、外连接

    原文:你真的会玩SQL吗?内连接.外连接 大多数人一般写多表查询会这样写select * from tbA ,tbB  没有用到JOIN关键字,太Low了,官网标准建议是用JOIN明确表间的关系,下面 ...

  4. SQL中的内连接与外连接

    关于关系代数连接运算的介绍请查看下面链接 http://www.cnblogs.com/xidongyu/articles/5980407.html 连接运算格式 链接运算由两部分构成:连接类型和连接 ...

  5. Sql中的内连接,左连接以及右连接区别

    转自:http://pangaoyuan.javaeye.com/blog/713177 有两个表A和表B. 表A结构如下: Aid:int:标识种子,主键,自增ID Aname:varchar 数据 ...

  6. 优化子查询sql语句为内连接

    背景: 希望提高查询的效率,从sql语句中频繁出现的子查询入手. 数据表如下:Student表中的CityCode对应于City表中的Code. Student表:                   ...

  7. SQL 交叉连接与内连接

    交叉连接 ,没有任何限制方式的连接. 叫做交叉连接. 碰到一种SQL 的写法. select * from  t1,t2 .     这其实是交叉连接 .   t1  是三条 ,  t2 是两条.  ...

  8. SQL中的内连接外连接和交叉连接是什么意思?

    内连接又分为等值连接.自然连接和不等连接三种. 外连接分为左外连接(LEFT OUTER JOIN或LEFT JOIN).右外连接(RIGHT OUTER JOIN或RIGHT JOIN)和全外连接( ...

  9. 清晰讲解SQL语句中的内连接,通用于Mysql和Oracle,全是干货哦

    本文章目的:力求清晰明了讲解SQL语句的内连接的各种应用,没有深奥的理解! 前奏:这篇文章和下篇文章会将内连接和外连接讲解清楚SQL语句的多表查询常用的有以下几种:两表联合查询(1)内连接(2)外连接 ...

随机推荐

  1. Codeforces Round #409(Div.2)

    传送门 题意 A.询问最多改变一个字符的字符串"VK"子串数量 B.f(x,z)=y,给出x,y,求z For example, f("ab", "b ...

  2. HDU2604:Queuing(矩阵快速幂+递推)

    传送门 题意 长为len的字符串只由'f','m'构成,有2^len种情况,问在其中不包含'fmf','fff'的字符串有多少个,此处将队列换成字符串 分析 矩阵快速幂写的比较崩,手生了,多练! 用f ...

  3. bzoj 3709: [PA2014]Bohater【贪心】

    先打能回血的,按消耗从小到大打: 然后按回血量降序打剩下的(把消耗和回血反着看就是上一种怪,打法一样): 中间体力小于0就输出无解 #include<iostream> #include& ...

  4. bzoj 2178 圆的面积并【simpson积分】

    直接套simpson,f可以直接把圆排序后扫一遍所有圆,这样维护一个区间就可以避免空段. 然而一定要去掉被其他圆完全覆盖的圆,否则会TLE #include<iostream> #incl ...

  5. 洛谷 P3254 圆桌问题【最大流】

    s向所有单位连流量为人数的边,所有饭桌向t连流量为饭桌容量的边,每个单位向每个饭桌连容量为1的边表示这个饭桌只能坐这个单位的一个人.跑dinic如果小于总人数则无解,否则对于每个单位for与它相连.满 ...

  6. Java之简单的四则运算

    简单的四则运算 请你编写程序实现能处理两个数的+.-.*./.%的表达式程序.数据的输入/输出全部使用标准输入/输出,输入数据的第一行为你需要计算表达式的个数,从第2行开始,每一行为你计算的一个表达式 ...

  7. JS开发备忘笔记-- Javascript中document.execCommand()的用法

    document.execCommand()方法处理Html数据时常用语法格式如下:document.execCommand(sCommand[,交互方式, 动态参数]) 其中:sCommand为指令 ...

  8. ————————C语言中快速排序方法——————————————

    在对浮点型排序是一定要用三木运算符(三目运算符内容下去自己看),因为如果也是用整形那样的减法的时候如果是两个十分相近的数字 可能返回一个小数(自己一会去试试),冉冉他cmp返回值是int(试试别的)因 ...

  9. Spring + MyBaits 日志初始化两遍的问题

    偶然发现一个问题,记录一下以备查询. 问题:系统启动时发现日志初始化了两次 14:28:04.798 [main] DEBUG org.apache.ibatis.logging.LogFactory ...

  10. _bzoj1036 [ZJOI2008]树的统计Count【树链剖分】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1036 保存模版. 执行qmax与qsum操作,往上爬的时候最开始的代码出了点小问题,往上爬的 ...