一條SQL語句查詢塊分解及查詢轉換
原始語句如下:
select BIZ_NO,
OUT_BIZ_NO,
ORDER_NO,
USER_ID,
user_name,
CARD_NO,
ACCOUNT_NO,
ACCOUNT_BIZ_NO,
USER_TYPE,
EVENT,
GID,
TRADE_AMOUNT,
DATA_BIZ_TYPE,
DIRECTION,
DATA_STATUS,
CURRENCY,
ACCOUNT_DAY,
COUNTER_PARTY_USER_ID,
counter_party_user_name,
COUNTER_PARTY_CARD_NO,
COUNTER_PARTY_ACCOUNT_NO,
product_code,
category,
origin,
TRADE_TYPE,
TRADE_BIZ_PRODUCT_CODE,
MERCHANT_USER_ID,
MERCHANT_CARD_NO,
MERCHANT_ACC_NO,
MERCHANT_ORDER_BIZ_NO,
INLET,
TRADE_FROM,
BIZ_IDENTITY,
bank_Code,
BANK_ACCOUNT_NO,
BANK_ACCOUNT_NAME,
CREATE_TIME,
FINISHED_TIME,
TRADE_NAME,
TRADE_MEMO,
BANK_CNAPS_NO,
BANK_NAME,
SETTLE_BIZ_NO,
SETTLE_CHANNEL_API,
settle_time,
relation_no,
retention_bank_no,
retention_bank_code,
refund_reason,
EXTEND_CONTEXT,
RAW_ADD_TIME,
RAW_UPDATE_TIME,
MEMO,
relation_time
from silverb.USER_TRANS_LOG
where 1 = 1
AND event = 'CHARGE'
AND ORDER_NO in
(select AA.OUT_BIZ_NO
from (SELECT a.*, ROWNUM RN
from (select OUT_BIZ_NO
from (select t.event || t.direction as EVENTINOUT,
t.*
from silverb.USER_TRANS_LOG t) X
where 1 = 1
and X.DATA_BIZ_TYPE in
('FAST_PAY',
'TRANSFER',
'REMITTANCE',
'CARDTOCARD',
'ESCROWTRADE',
'EBANK',
'OFFLINE',
'DEDUCT',
'QUICK',
'CERTIFY',
'VERIFY',
'WITHDRAW_SINGLE',
'WITHDRAW_FORCEING',
'WITHDRAW_OFFLINE',
'DEPOSITBACK')
and X.eventinout in ('DEPOSITBACKIN',
'WITHDRAW_FLUSHES_WRITEOFFOUT',
'DEPOSIT_FLUSHES_FILLACCOUNTSIN',
'TRADE_SHARE_REFUNDOUT',
'TRADE_REFUNDOUT',
'WITHDRAW_FLUSHES_FILLACCOUNTSOUT',
'TRADE_FLUSHES_WRITEOFFOUT',
'WITHDRAWOUT',
'DISHONOUROUT',
'DEPOSITIN',
'TRADE_FLUSHES_FILLACCOUNTSOUT',
'DEPOSITBACK_FLUSHES_WRITEOFFIN',
'DEPOSIT_FLUSHES_WRITEOFFIN',
'DEPOSITBACK_FLUSHES_FILLACCOUNTSIN',
'TRADEOUT')
and X.event not in ('TRADE_SHARE', 'CHARGE')
and X.MERCHANT_USER_ID = '20140730020001144381'
and X.create_time >=
to_date('2015-01-01 00:00:00',
'yyyy-mm-dd hh24:mi:ss')
and X.create_time <
to_date('2015-02-18 23:59:59',
'yyyy-mm-dd hh24:mi:ss')
order by create_time desc) a
where ROWNUM <= 100) AA
where RN >= 1)
and DIRECTION = 'OUT'
and create_time >=
to_date('2015-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss')
and create_time <
to_date('2015-03-18 23:59:59', 'yyyy-mm-dd hh24:mi:ss')
執行計劃
----------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 470 (100)| | | |
| 1 | NESTED LOOPS | | | | | | | |
| 2 | NESTED LOOPS | | 8 | 4152 | 470 (7)| 00:00:01 | | |
| 3 | VIEW | VW_NSO_1 | 8 | 336 | 253 (9)| 00:00:01 | | |
| 4 | HASH UNIQUE | | 8 | 120 | | | | |
|* 5 | VIEW | | 8 | 120 | 253 (9)| 00:00:01 | | |
|* 6 | COUNT STOPKEY | | | | | | | |
| 7 | VIEW | | 8 | 152 | 253 (9)| 00:00:01 | | |
|* 8 | SORT ORDER BY STOPKEY | | 8 | 552 | 253 (9)| 00:00:01 | | |
| 9 | PARTITION RANGE ITERATOR | | 8 | 552 | 252 (9)| 00:00:01 | 34 | 33 |
| 10 | PARTITION HASH ALL | | 8 | 552 | 252 (9)| 00:00:01 | 4 | 1 |
|* 11 | TABLE ACCESS BY LOCAL INDEX ROWID| USER_TRANS_LOG | 8 | 552 | 252 (9)| 00:00:01 |
|* 12 | INDEX RANGE SCAN | ME_L_IND | 1770 | | 27 (12)| 00:00:01 | 136 | 12
| 13 | PARTITION RANGE ITERATOR | | 1 | | 25 (4)| 00:00:01 | 33 | 35
| 14 | PARTITION HASH ALL | | 1 | | 25 (4)| 00:00:01 | 1 | 4 |
|* 15 | INDEX RANGE SCAN | ORDER_L_IND | 1 | | 25 (4)| 00:00:01 | 129 |
|* 16 | TABLE ACCESS BY LOCAL INDEX ROWID | USER_TRANS_LOG | 1 | 477 | 27 (4)| 00:00:0
----------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$5DA710D3
3 - SEL$683B0107 / VW_NSO_1@SEL$5DA710D3
4 - SEL$683B0107
5 - SEL$3 / AA@SEL$2
6 - SEL$3
7 - SEL$7286615E / A@SEL$3
8 - SEL$7286615E
11 - SEL$7286615E / T@SEL$5
12 - SEL$7286615E / T@SEL$5
15 - SEL$5DA710D3 / USER_TRANS_LOG@SEL$1
16 - SEL$5DA710D3 / USER_TRANS_LOG@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
5 - filter("RN">=1)
6 - filter(ROWNUM<=100)
8 - filter(ROWNUM<=100)
11 - filter(("T"."EVENT"<>'CHARGE' AND ("T"."EVENT"||"T"."DIRECTION"='DEPOSITBACKIN' OR
"T"."EVENT"||"T"."DIRECTION"='WITHDRAW_FLUSHES_WRITEOFFOUT' OR
"T"."EVENT"||"T"."DIRECTION"='DEPOSIT_FLUSHES_FILLACCOUNTSIN' OR "T"."EVENT"||"T"."DIRECTION"
OR "T"."EVENT"||"T"."DIRECTION"='TRADE_REFUNDOUT' OR "T"."EVENT"||"T"."DIRECTION"='WITHDRAW_F
OR "T"."EVENT"||"T"."DIRECTION"='TRADE_FLUSHES_WRITEOFFOUT' OR "T"."EVENT"||"T"."DIRECTION"='
"T"."EVENT"||"T"."DIRECTION"='DISHONOUROUT' OR "T"."EVENT"||"T"."DIRECTION"='DEPOSITIN' OR
"T"."EVENT"||"T"."DIRECTION"='TRADE_FLUSHES_FILLACCOUNTSOUT' OR
"T"."EVENT"||"T"."DIRECTION"='DEPOSITBACK_FLUSHES_WRITEOFFIN' OR
"T"."EVENT"||"T"."DIRECTION"='DEPOSIT_FLUSHES_WRITEOFFIN' OR
"T"."EVENT"||"T"."DIRECTION"='DEPOSITBACK_FLUSHES_FILLACCOUNTSIN' OR "T"."EVENT"||"T"."DIRECT
INTERNAL_FUNCTION("T"."DATA_BIZ_TYPE") AND "T"."CREATE_TIME"
"T"."EVENT"<>'TRADE_SHARE'))
12 - access("T"."MERCHANT_USER_ID"='20140730020001144381')
15 - access("ORDER_NO"="OUT_BIZ_NO")
16 - filter(("EVENT"='CHARGE' AND "DIRECTION"='OUT' AND "CREATE_TIME"
分解:
1、T@SEL$5(別名為T的查詢塊5)
select t.event || t.direction as EVENTINOUT,t.* from silverb.USER_TRANS_LOG t
2、X@SEL$4(別名為X的查詢塊4)雖然執行計劃中沒有出現這個查詢塊,但是在10053TRACE是有的,其實他是做的檢視合併的結果
select OUT_BIZ_NO from (子查詢塊T) where X.DATA_BIZ_TYPE in('FAST_PAY',...)
and X.eventinout in ('DEPOSITBACKIN',...)
and X.event not in ('TRADE_SHARE', 'CHARGE')
and X.MERCHANT_USER_ID = '20140730020001144381'
and X.create_time >=to_date('2015-01-01 00:00:00','yyyy-mm-dd hh24:mi:ss')
and X.create_time
order by create_time desc
3、EL$7286615E 此查詢塊名字為資料庫自動生成,表示進行簡單檢視合併後的查詢塊
10053 中明確標示
Registered qb: SEL$7286615E 0x5924a390 (VIEW MERGE SEL$4; SEL$5)
4、A@SEL$3(別名為A的查詢塊3)
SELECT a.*, ROWNUM RN from (子查詢塊X) a where ROWNUM <= 100
5、AA@SEL$2(別名為AA的查詢塊2)
select AA.OUT_BIZ_NO from (子查詢塊A) AA where RN >= 1
6、SEL$683B0107 此查詢塊,名字為資料庫自動生成,表示進行子複雜查詢展開的查詢塊
這裡應該是使用了DISTINCT(AA.OUT_BIZ_NO) 來替換查詢塊AA@SEL$2中的AA.OUT_BIZ_NO
這一點從執行計劃中的HASH UNIQUE也得到了驗證
10053 中明確標示
SU: Transform an ANY subquery to semi-join or distinct.
SEL$683B0107 0x58e85660 (SUBQ INTO VIEW FOR COMPLEX UNNEST SEL$2)
7、USER_TRANS_LOG@SEL$1(表名為A的查詢塊1)
select BIZ_NO,... from silverb.USER_TRANS_LOG
where 1 = 1 AND event = 'CHARGE' AND ORDER_NO in
(子查詢塊A)
and DIRECTION = 'OUT'
and create_time >= to_date('2015-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss')
and create_time < to_date('2015-03-18 23:59:59', 'yyyy-mm-dd hh24:mi:ss')
8、SEL$5DA710D3 此查詢塊,名字為資料庫自動生成,表示進行子查詢展開的查詢塊,此處將
子查詢ORDER_NO in (子查詢塊A)轉換NEST LOOP的方式進行
10053 中明確標示
SEL$5DA710D3 0x591f6a80 (SUBQUERY UNNEST SEL$1; SEL$2) [FINAL]
所以本語句的執行順序為
1、查詢塊T@SEL$5和X@SEL$4先進行檢視合併,生成查詢塊EL$7286615E,對應執行計劃的8-12步,並且A@SEL$3分頁查詢的謂詞ROWNUM <= 100
推入到此檢視中,形成了SORT ORDER BY STOPKEY,形成一個VIEW
2、查詢塊@SEL$3不能進行檢視合併,因為包含了ROWNUM,對應執行計劃的6-7步,使用到謂詞ROWNUM <= 100,形成第二個VIEW
3、查詢塊@SEL$2透過COMPLEX UNNEST形成了SEL$683B0107,對應執行計劃的4-5步,使用謂詞"RN">=1和distinct(AA.OUT_BIZ_NO),形成第三個VIEW(VW_NSO_1)
4、查詢塊USER_TRANS_LOG@SEL$1與SEL$683B0107最終進行子查詢展開得到了最終的查詢塊SEL$5DA710D3,進行了2次NETS LOOP 進行完成了所有的步驟,
注意這裡並沒有完全的展開,而是把子查詢當做一個檢視或進行了處理,因為檢視本生是一個複雜的子查詢得出,而是轉換為JION的方式。
這些操作實際上在Outline Data中也有體現
MERGE(@"SEL$5")
UNNEST(@"SEL$2")
關於查詢塊的說明:
ORACLE查詢塊是語義上完整的查詢語句,原則上是從內到外的 型別$數字 的命名方式,數字從1向上遞增(來源:基於ORACLE的最佳化法則)
關於10053中關於查詢轉換的說明:
10053中的第一部分就列出執行了哪些查詢轉換其型別也在其中有說明如下
Legend
The following abbreviations are used by optimizer trace.
CBQT - cost-based query transformation
JPPD - join predicate push-down
OJPPD - old-style (non-cost-based) JPPD
FPD - filter push-down
PM - predicate move-around
CVM - complex view merging
SPJ - select-project-join
SJC - set join conversion
SU - subquery unnesting
OBYE - order by elimination
OST - old style star transformation
ST - new (cbqt) star transformation
CNT - count(col) to count(*) transformation
JE - Join Elimination
JF - join factorization
SLP - select list pruning
DP - distinct placement
qb - query block
LB - leaf blocks
DK - distinct keys
LB/K - average number of leaf blocks per key
DB/K - average number of data blocks per key
CLUF - clustering factor
NDV - number of distinct values
Resp - response cost
Card - cardinality
Resc - resource cost
NL - nested loops (join)
SM - sort merge (join)
HA - hash (join)
CPUSPEED - CPU Speed
IOTFRSPEED - I/O transfer speed
IOSEEKTIM - I/O seek time
SREADTIM - average single block read time
MREADTIM - average multiblock read time
MBRC - average multiblock read count
MAXTHR - maximum I/O system throughput
SLAVETHR - average slave I/O throughput
dmeth - distribution method
1: no partitioning required
2: value partitioned
4: right is random (round-robin)
128: left is random (round-robin)
8: broadcast right and partition left
16: broadcast left and partition right
32: partition left using partitioning of right
64: partition right using partitioning of left
256: run the join in serial
0: invalid distribution method
sel - selectivity
ptn - partition
select BIZ_NO,
OUT_BIZ_NO,
ORDER_NO,
USER_ID,
user_name,
CARD_NO,
ACCOUNT_NO,
ACCOUNT_BIZ_NO,
USER_TYPE,
EVENT,
GID,
TRADE_AMOUNT,
DATA_BIZ_TYPE,
DIRECTION,
DATA_STATUS,
CURRENCY,
ACCOUNT_DAY,
COUNTER_PARTY_USER_ID,
counter_party_user_name,
COUNTER_PARTY_CARD_NO,
COUNTER_PARTY_ACCOUNT_NO,
product_code,
category,
origin,
TRADE_TYPE,
TRADE_BIZ_PRODUCT_CODE,
MERCHANT_USER_ID,
MERCHANT_CARD_NO,
MERCHANT_ACC_NO,
MERCHANT_ORDER_BIZ_NO,
INLET,
TRADE_FROM,
BIZ_IDENTITY,
bank_Code,
BANK_ACCOUNT_NO,
BANK_ACCOUNT_NAME,
CREATE_TIME,
FINISHED_TIME,
TRADE_NAME,
TRADE_MEMO,
BANK_CNAPS_NO,
BANK_NAME,
SETTLE_BIZ_NO,
SETTLE_CHANNEL_API,
settle_time,
relation_no,
retention_bank_no,
retention_bank_code,
refund_reason,
EXTEND_CONTEXT,
RAW_ADD_TIME,
RAW_UPDATE_TIME,
MEMO,
relation_time
from silverb.USER_TRANS_LOG
where 1 = 1
AND event = 'CHARGE'
AND ORDER_NO in
(select AA.OUT_BIZ_NO
from (SELECT a.*, ROWNUM RN
from (select OUT_BIZ_NO
from (select t.event || t.direction as EVENTINOUT,
t.*
from silverb.USER_TRANS_LOG t) X
where 1 = 1
and X.DATA_BIZ_TYPE in
('FAST_PAY',
'TRANSFER',
'REMITTANCE',
'CARDTOCARD',
'ESCROWTRADE',
'EBANK',
'OFFLINE',
'DEDUCT',
'QUICK',
'CERTIFY',
'VERIFY',
'WITHDRAW_SINGLE',
'WITHDRAW_FORCEING',
'WITHDRAW_OFFLINE',
'DEPOSITBACK')
and X.eventinout in ('DEPOSITBACKIN',
'WITHDRAW_FLUSHES_WRITEOFFOUT',
'DEPOSIT_FLUSHES_FILLACCOUNTSIN',
'TRADE_SHARE_REFUNDOUT',
'TRADE_REFUNDOUT',
'WITHDRAW_FLUSHES_FILLACCOUNTSOUT',
'TRADE_FLUSHES_WRITEOFFOUT',
'WITHDRAWOUT',
'DISHONOUROUT',
'DEPOSITIN',
'TRADE_FLUSHES_FILLACCOUNTSOUT',
'DEPOSITBACK_FLUSHES_WRITEOFFIN',
'DEPOSIT_FLUSHES_WRITEOFFIN',
'DEPOSITBACK_FLUSHES_FILLACCOUNTSIN',
'TRADEOUT')
and X.event not in ('TRADE_SHARE', 'CHARGE')
and X.MERCHANT_USER_ID = '20140730020001144381'
and X.create_time >=
to_date('2015-01-01 00:00:00',
'yyyy-mm-dd hh24:mi:ss')
and X.create_time <
to_date('2015-02-18 23:59:59',
'yyyy-mm-dd hh24:mi:ss')
order by create_time desc) a
where ROWNUM <= 100) AA
where RN >= 1)
and DIRECTION = 'OUT'
and create_time >=
to_date('2015-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss')
and create_time <
to_date('2015-03-18 23:59:59', 'yyyy-mm-dd hh24:mi:ss')
執行計劃
----------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
----------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 470 (100)| | | |
| 1 | NESTED LOOPS | | | | | | | |
| 2 | NESTED LOOPS | | 8 | 4152 | 470 (7)| 00:00:01 | | |
| 3 | VIEW | VW_NSO_1 | 8 | 336 | 253 (9)| 00:00:01 | | |
| 4 | HASH UNIQUE | | 8 | 120 | | | | |
|* 5 | VIEW | | 8 | 120 | 253 (9)| 00:00:01 | | |
|* 6 | COUNT STOPKEY | | | | | | | |
| 7 | VIEW | | 8 | 152 | 253 (9)| 00:00:01 | | |
|* 8 | SORT ORDER BY STOPKEY | | 8 | 552 | 253 (9)| 00:00:01 | | |
| 9 | PARTITION RANGE ITERATOR | | 8 | 552 | 252 (9)| 00:00:01 | 34 | 33 |
| 10 | PARTITION HASH ALL | | 8 | 552 | 252 (9)| 00:00:01 | 4 | 1 |
|* 11 | TABLE ACCESS BY LOCAL INDEX ROWID| USER_TRANS_LOG | 8 | 552 | 252 (9)| 00:00:01 |
|* 12 | INDEX RANGE SCAN | ME_L_IND | 1770 | | 27 (12)| 00:00:01 | 136 | 12
| 13 | PARTITION RANGE ITERATOR | | 1 | | 25 (4)| 00:00:01 | 33 | 35
| 14 | PARTITION HASH ALL | | 1 | | 25 (4)| 00:00:01 | 1 | 4 |
|* 15 | INDEX RANGE SCAN | ORDER_L_IND | 1 | | 25 (4)| 00:00:01 | 129 |
|* 16 | TABLE ACCESS BY LOCAL INDEX ROWID | USER_TRANS_LOG | 1 | 477 | 27 (4)| 00:00:0
----------------------------------------------------------------------------------------------------
Query Block Name / Object Alias (identified by operation id):
-------------------------------------------------------------
1 - SEL$5DA710D3
3 - SEL$683B0107 / VW_NSO_1@SEL$5DA710D3
4 - SEL$683B0107
5 - SEL$3 / AA@SEL$2
6 - SEL$3
7 - SEL$7286615E / A@SEL$3
8 - SEL$7286615E
11 - SEL$7286615E / T@SEL$5
12 - SEL$7286615E / T@SEL$5
15 - SEL$5DA710D3 / USER_TRANS_LOG@SEL$1
16 - SEL$5DA710D3 / USER_TRANS_LOG@SEL$1
Predicate Information (identified by operation id):
---------------------------------------------------
5 - filter("RN">=1)
6 - filter(ROWNUM<=100)
8 - filter(ROWNUM<=100)
11 - filter(("T"."EVENT"<>'CHARGE' AND ("T"."EVENT"||"T"."DIRECTION"='DEPOSITBACKIN' OR
"T"."EVENT"||"T"."DIRECTION"='WITHDRAW_FLUSHES_WRITEOFFOUT' OR
"T"."EVENT"||"T"."DIRECTION"='DEPOSIT_FLUSHES_FILLACCOUNTSIN' OR "T"."EVENT"||"T"."DIRECTION"
OR "T"."EVENT"||"T"."DIRECTION"='TRADE_REFUNDOUT' OR "T"."EVENT"||"T"."DIRECTION"='WITHDRAW_F
OR "T"."EVENT"||"T"."DIRECTION"='TRADE_FLUSHES_WRITEOFFOUT' OR "T"."EVENT"||"T"."DIRECTION"='
"T"."EVENT"||"T"."DIRECTION"='DISHONOUROUT' OR "T"."EVENT"||"T"."DIRECTION"='DEPOSITIN' OR
"T"."EVENT"||"T"."DIRECTION"='TRADE_FLUSHES_FILLACCOUNTSOUT' OR
"T"."EVENT"||"T"."DIRECTION"='DEPOSITBACK_FLUSHES_WRITEOFFIN' OR
"T"."EVENT"||"T"."DIRECTION"='DEPOSIT_FLUSHES_WRITEOFFIN' OR
"T"."EVENT"||"T"."DIRECTION"='DEPOSITBACK_FLUSHES_FILLACCOUNTSIN' OR "T"."EVENT"||"T"."DIRECT
INTERNAL_FUNCTION("T"."DATA_BIZ_TYPE") AND "T"."CREATE_TIME"
12 - access("T"."MERCHANT_USER_ID"='20140730020001144381')
15 - access("ORDER_NO"="OUT_BIZ_NO")
16 - filter(("EVENT"='CHARGE' AND "DIRECTION"='OUT' AND "CREATE_TIME"
分解:
1、T@SEL$5(別名為T的查詢塊5)
select t.event || t.direction as EVENTINOUT,t.* from silverb.USER_TRANS_LOG t
2、X@SEL$4(別名為X的查詢塊4)雖然執行計劃中沒有出現這個查詢塊,但是在10053TRACE是有的,其實他是做的檢視合併的結果
select OUT_BIZ_NO from (子查詢塊T) where X.DATA_BIZ_TYPE in('FAST_PAY',...)
and X.eventinout in ('DEPOSITBACKIN',...)
and X.event not in ('TRADE_SHARE', 'CHARGE')
and X.MERCHANT_USER_ID = '20140730020001144381'
and X.create_time >=to_date('2015-01-01 00:00:00','yyyy-mm-dd hh24:mi:ss')
and X.create_time
3、EL$7286615E 此查詢塊名字為資料庫自動生成,表示進行簡單檢視合併後的查詢塊
10053 中明確標示
Registered qb: SEL$7286615E 0x5924a390 (VIEW MERGE SEL$4; SEL$5)
4、A@SEL$3(別名為A的查詢塊3)
SELECT a.*, ROWNUM RN from (子查詢塊X) a where ROWNUM <= 100
5、AA@SEL$2(別名為AA的查詢塊2)
select AA.OUT_BIZ_NO from (子查詢塊A) AA where RN >= 1
6、SEL$683B0107 此查詢塊,名字為資料庫自動生成,表示進行子複雜查詢展開的查詢塊
這裡應該是使用了DISTINCT(AA.OUT_BIZ_NO) 來替換查詢塊AA@SEL$2中的AA.OUT_BIZ_NO
這一點從執行計劃中的HASH UNIQUE也得到了驗證
10053 中明確標示
SU: Transform an ANY subquery to semi-join or distinct.
SEL$683B0107 0x58e85660 (SUBQ INTO VIEW FOR COMPLEX UNNEST SEL$2)
7、USER_TRANS_LOG@SEL$1(表名為A的查詢塊1)
select BIZ_NO,... from silverb.USER_TRANS_LOG
where 1 = 1 AND event = 'CHARGE' AND ORDER_NO in
(子查詢塊A)
and DIRECTION = 'OUT'
and create_time >= to_date('2015-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss')
and create_time < to_date('2015-03-18 23:59:59', 'yyyy-mm-dd hh24:mi:ss')
8、SEL$5DA710D3 此查詢塊,名字為資料庫自動生成,表示進行子查詢展開的查詢塊,此處將
子查詢ORDER_NO in (子查詢塊A)轉換NEST LOOP的方式進行
10053 中明確標示
SEL$5DA710D3 0x591f6a80 (SUBQUERY UNNEST SEL$1; SEL$2) [FINAL]
所以本語句的執行順序為
1、查詢塊T@SEL$5和X@SEL$4先進行檢視合併,生成查詢塊EL$7286615E,對應執行計劃的8-12步,並且A@SEL$3分頁查詢的謂詞ROWNUM <= 100
推入到此檢視中,形成了SORT ORDER BY STOPKEY,形成一個VIEW
2、查詢塊@SEL$3不能進行檢視合併,因為包含了ROWNUM,對應執行計劃的6-7步,使用到謂詞ROWNUM <= 100,形成第二個VIEW
3、查詢塊@SEL$2透過COMPLEX UNNEST形成了SEL$683B0107,對應執行計劃的4-5步,使用謂詞"RN">=1和distinct(AA.OUT_BIZ_NO),形成第三個VIEW(VW_NSO_1)
4、查詢塊USER_TRANS_LOG@SEL$1與SEL$683B0107最終進行子查詢展開得到了最終的查詢塊SEL$5DA710D3,進行了2次NETS LOOP 進行完成了所有的步驟,
注意這裡並沒有完全的展開,而是把子查詢當做一個檢視或進行了處理,因為檢視本生是一個複雜的子查詢得出,而是轉換為JION的方式。
這些操作實際上在Outline Data中也有體現
MERGE(@"SEL$5")
UNNEST(@"SEL$2")
關於查詢塊的說明:
ORACLE查詢塊是語義上完整的查詢語句,原則上是從內到外的 型別$數字 的命名方式,數字從1向上遞增(來源:基於ORACLE的最佳化法則)
關於10053中關於查詢轉換的說明:
10053中的第一部分就列出執行了哪些查詢轉換其型別也在其中有說明如下
Legend
The following abbreviations are used by optimizer trace.
CBQT - cost-based query transformation
JPPD - join predicate push-down
OJPPD - old-style (non-cost-based) JPPD
FPD - filter push-down
PM - predicate move-around
CVM - complex view merging
SPJ - select-project-join
SJC - set join conversion
SU - subquery unnesting
OBYE - order by elimination
OST - old style star transformation
ST - new (cbqt) star transformation
CNT - count(col) to count(*) transformation
JE - Join Elimination
JF - join factorization
SLP - select list pruning
DP - distinct placement
qb - query block
LB - leaf blocks
DK - distinct keys
LB/K - average number of leaf blocks per key
DB/K - average number of data blocks per key
CLUF - clustering factor
NDV - number of distinct values
Resp - response cost
Card - cardinality
Resc - resource cost
NL - nested loops (join)
SM - sort merge (join)
HA - hash (join)
CPUSPEED - CPU Speed
IOTFRSPEED - I/O transfer speed
IOSEEKTIM - I/O seek time
SREADTIM - average single block read time
MREADTIM - average multiblock read time
MBRC - average multiblock read count
MAXTHR - maximum I/O system throughput
SLAVETHR - average slave I/O throughput
dmeth - distribution method
1: no partitioning required
2: value partitioned
4: right is random (round-robin)
128: left is random (round-robin)
8: broadcast right and partition left
16: broadcast left and partition right
32: partition left using partitioning of right
64: partition right using partitioning of left
256: run the join in serial
0: invalid distribution method
sel - selectivity
ptn - partition
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-1456171/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- [20201214]查詢隱式轉換的sql語句.txtSQL
- 20201214]查詢隱式轉換的sql語句.txtSQL
- sql查詢語句流程SQL
- SQL mother查詢語句SQL
- SQL查詢語句 (Oracle)SQLOracle
- 一條 SQL 查詢語句是如何執行的?SQL
- 使用sql語句查詢平均值,使用sql語句查詢資料總條數, not in 篩選語句的使用SQL
- 一條查詢語句的執行流程
- SQL-基礎語法 - 條件查詢 - 模糊查詢SQL
- postgresql dba常用sql查詢語句SQL
- MySQL系列之一條SQL查詢語句的執行過程MySql
- 記一個實用的sql查詢語句SQL
- mysql查詢效率慢的SQL語句MySql
- SQL單表查詢語句總結SQL
- SQL Server 語句日期格式查詢方法SQLServer
- SQL Server-簡單查詢語句SQLServer
- 【SQL】Oracle查詢轉換之物化檢視查詢重寫SQLOracle
- 【SQL】Oracle查詢轉換之 OR用法SQLOracle
- mysql查詢語句5:連線查詢MySql
- 一文讀懂一條 SQL 查詢語句是如何執行的SQL
- oracle查詢語句查詢增加一列內容Oracle
- mysql查詢語句MySql
- 查詢策略選擇:使用 JOIN 還是多條 SQL 語句SQL
- 深入理解mongodb查詢條件語句MongoDB
- 在mysql查詢效率慢的SQL語句MySql
- Laravel 框架查詢執行的 SQL 語句Laravel框架SQL
- SQL基礎的查詢語句烈鉍SQL
- 01 | 基礎架構:一條SQL查詢語句是如何執行的?架構SQL
- SQL Server 查詢歷史執行的SQL語句SQLServer
- 《MySQL慢查詢優化》之SQL語句及索引優化MySql優化索引
- Mysql之查詢語句MySql
- mysql查詢語句集MySql
- SQL語句替換查詢結果的的寫法舉例SQL
- Oracle 查詢轉換Oracle
- Sql語句本身的優化-定位慢查詢SQL優化
- GaussDB SQL查詢語句執行過程解析SQL
- SQL 查詢語句的執行順序解析SQL
- MySQL資料庫:7、SQL常用查詢語句MySql資料庫
- [20210112]ashtop查詢特定表的SQL語句.txtSQL