【DB筆試面試586】在Oracle中,什麼是自適應游標共享(2)?
- 2019 年 10 月 10 日
- 筆記
另外,在目標列有Frequency類型直方圖的前提條件下,如果對目標列施加等值查詢條件,且該查詢條件的輸入值等於該列的某個實際值時,則該謂詞條件的可選擇率的計算公式為如下所示:
selectivity=BucketSize/NUM_ROWS
其中,BucketSize表示目標列的某個實際值所對應的記錄數。
合併上述計算公式可以得出,對於表TI而言,在當前情形下V$SQL_CS_SELECTIVITY中記錄的可選擇率的範圍的計算公式為[0.9*BucketSize/NUM_ROWS,1.1*BucketSize/NUM_ROWS]。
對於上述CHILD NUMBER為1的Child Cursor而言,綁定變數攴的輸入值為「TABLE」時對應的記錄數為61818(即BucketSize的值是61818),表Tl的記錄數為78174(即NUM_ROWS的值為78174),將61818和78174帶入上述合併後的計算公式:
LHR@orclasm > SELECT d.NUM_ROWS FROM dba_tables d WHERE d.TABLE_NAME='T_ACS_20170611_LHR'; NUM_ROWS ---------- 78174 LHR@orclasm > SELECT ROUND(0.9*(61818/78174),6) low,ROUND(1.1*(61818/78174),6) HIGH FROM DUAL; LOW HIGH ---------- ---------- 0.711697 0.869852 --從上述計算結果可以看出,可選擇率範圍和之前從VSSQL_CS_SELECTIVITY中查到的結果完全一致。 --現在將X的值修改為「INDEX」: LHR@orclasm > EXEC :X :='INDEX'; PL/SQL procedure successfully completed. LHR@orclasm > SELECT COUNT(*) FROM T_ACS_20170611_LHR T WHERE T.OBJECT_TYPE=:X; COUNT(*) ---------- 3082 LHR@orclasm > LHR@orclasm > SELECT A.SQL_TEXT, A.SQL_ID,A.VERSION_COUNT,A.EXECUTIONS FROM V$SQLAREA A WHERE A.SQL_TEXT LIKE 'SELECT COUNT(*) FROM T_ACS_20170611_LHR T WHERE T.OBJECT_TYPE=%'; SQL_TEXT SQL_ID VERSION_COUNT EXECUTIONS ---------------------------------------------------------------------------------------- ------------- ------------- ---------- SELECT COUNT(*) FROM T_ACS_20170611_LHR T WHERE T.OBJECT_TYPE=:X bt8tk3f1tnwcf 3 4 LHR@orclasm > SELECT A.SQL_ID,A.CHILD_NUMBER,A.EXECUTIONS,A.BUFFER_GETS,A.IS_BIND_SENSITIVE,A.IS_BIND_AWARE,A.IS_SHAREABLE,A.PLAN_HASH_VALUE FROM V$SQL A WHERE A.SQL_ID='bt8tk3f1tnwcf'; SQL_ID CHILD_NUMBER EXECUTIONS BUFFER_GETS I I I PLAN_HASH_VALUE ------------- ------------ ---------- ----------- - - - --------------- bt8tk3f1tnwcf 0 2 309 Y N N 3002671579 bt8tk3f1tnwcf 1 1 522 Y Y Y 4256744017 bt8tk3f1tnwcf 2 1 16 Y Y Y 3002671579 LHR@orclasm >
從如下查詢結果可以看到,目標SQL對應的列VERSION_COUNT的值從之前的2變為現在的3,列EXECUTIONS的值為4,說明Oracle在第4次執行該SQL時依然用的是硬解析。目標SQL多了一個CHILD_NUMBER為2的新Child Cursor,且該Child Cursor對應的IS_BIND_SENSITIVE、IS_BIND_AWARE和IS_SHAREABLE的值均為Y,但是這個新Child Cursor和CHILD_NUMBER為0的原有Child Cursor的對應PLAN_HASH_VALUE的值均為3002671579(說明這兩個Child Cursor中存儲的執行計劃是相同的),而且CHILD_NUMBER為0的原有Child Cursor對應IS_SHAREABLE的值己經從之前的Y變為現在的N。
這些變化表明,對於標記為Bind Aware的Child Cursor所對應的目標SQL,當該SQL後續再次被執行時如果對應的是硬解析,且本次硬解析所產生的執行計劃和原有Child Cursor中存儲的執行計劃相同,則Oracle此時除了會新生成一個Child Cursor之外,還會把存儲相同執行計劃的原有Child Cursor標記為非共享(把原有Child Cursor在V$SQL中對應記錄的列IS SHAREABLE的值從Y改為N)。
目標SQL現在的執行計劃如下所示:
LHR@orclasm > SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('bt8tk3f1tnwcf',2,'advanced')); PLAN_TABLE_OUTPUT --------------------------------------------------------------------------------------- SQL_ID bt8tk3f1tnwcf, child number 2 ------------------------------------- SELECT COUNT(*) FROM T_ACS_20170611_LHR T WHERE T.OBJECT_TYPE=:X Plan hash value: 3002671579 --------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 15 (100)| | | 1 | SORT AGGREGATE | | 1 | 7 | | | |* 2 | INDEX RANGE SCAN| IDX_ACS_OBJID_LHR | 3082 | 21574 | 15 (0)| 00:00:01 | --------------------------------------------------------------------------------------- Query Block Name / Object Alias (identified by operation id): ------------------------------------------------------------- 1 - SEL$1 2 - SEL$1 / T@SEL$1 Outline Data ------------- /*+ BEGIN_OUTLINE_DATA IGNORE_OPTIM_EMBEDDED_HINTS OPTIMIZER_FEATURES_ENABLE('11.2.0.3') DB_VERSION('11.2.0.3') ALL_ROWS OUTLINE_LEAF(@"SEL$1") INDEX(@"SEL$1" "T"@"SEL$1" ("T_ACS_20170611_LHR"."OBJECT_TYPE")) END_OUTLINE_DATA */ Peeked Binds (identified by position): -------------------------------------- 1 - :X (VARCHAR2(30), CSID=852): 'INDEX' Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("T"."OBJECT_TYPE"=:X) Column Projection Information (identified by operation id): ----------------------------------------------------------- 1 - (#keys=0) COUNT(*)[22] 49 rows selected.
從上述顯示內容可以看出,目標SQL現在的執行計劃是走對索引IDX_ACS_OBJID_LHR的索引範圍掃描,確實與CHILD_NUMBER為0的原有Child Cursor中存儲的執行計劃相同。注意到「Peeked Binds」部分的內容為「1 – :X (VARCHAR2(30), CSID=852): 'INDEX'」,這說明Oracle在硬解析目標SQL的過程中確實再次使用了綁定變數窺探,而且做「窺探」這個動作時看到的綁定變數的輸入值為「INDEX」。
現在的問題是,既然Oracle此時選擇的執行計劃與原有Child Cursor中存儲的執行計劃相同,為什麼不直接沿用原先的執行計劃而是還得再做一次硬解析呢?
在介紹自適應游標共享的整體執行流程時曾經提到過:對於標記為Bind Aware的Child Cursor所對應的目標SQL,當該SQL再次被執行時,Oracle就會根據當前傳入的綁定變數值所對應的謂詞條件的可選擇率,來決定該SQL此時的執行是用硬解析還是用軟解析/軟軟解析。
對於上述CHILD_NUMBER為2的Child Cursor,綁定變數攴的輸入值為「INDEX」時對應的記錄數為3082,表TI的記錄數為78174,帶入合併後的計算公式:
LHR@orclasm > SELECT ROUND(0.9*(3082/78174),6) low,ROUND(1.1*(3082/78174),6) HIGH FROM DUAL; LOW HIGH ---------- ---------- 0.035482 0.043367 LHR@orclasm > SELECT * FROM V$SQL_CS_SELECTIVITY D WHERE D.SQL_ID='bt8tk3f1tnwcf' ORDER BY CHILD_NUMBER; ADDRESS HASH_VALUE SQL_ID CHILD_NUMBER PREDICATE RANGE_ID LOW HIGH ---------------- ---------- ------------- ------------ ---------------------------------------- ---------- ---------- ---------- 00000000AA2108A8 2207936910 bt8tk3f1tnwcf 1 =X 0 0.711697 0.869852 00000000AA2108A8 2207936910 bt8tk3f1tnwcf 2 =X 0 0.035482 0.043367 LHR@orclasm > SELECT * FROM V$SQL_CS_STATISTICS D WHERE D.SQL_ID='bt8tk3f1tnwcf' ORDER BY D.CHILD_NUMBER; ADDRESS HASH_VALUE SQL_ID CHILD_NUMBER BIND_SET_HASH_VALUE P EXECUTIONS ROWS_PROCESSED BUFFER_GETS CPU_TIME ---------------- ---------- ------------- ------------ ------------------- - ---------- -------------- ----------- ---------- 00000000AA2108A8 2207936910 bt8tk3f1tnwcf 0 821942781 Y 1 3 54 0 00000000AA2108A8 2207936910 bt8tk3f1tnwcf 1 3197905255 Y 1 61819 522 0 00000000AA2108A8 2207936910 bt8tk3f1tnwcf 2 3279106319 Y 1 3083 16 0 LHR@orclasm >
從上述計算結果可以看出,現在CHILD_NUMBER為2的Child Cursor對應的可選擇率的範圍為[0.035482,0.043367],根本就不在之前VSSQL_CS_SELECTIVITY中記錄的CHILD_NUMBER為1的Child Cursor所在的可選擇率的範圍[0.711697,0.869852]之內,所以Oracle此時還是得用硬解析。
由於上述CHILD_NUMBER為2的Child Cursor也是Bind Aware的,所以其對應的可選擇率也被記錄在了VSSQL_CS_SELECTIVITY中。
注意,這裡不存在Cursor合併的過程,因為Cursor合併是指Oracle會合併存儲相同執行計劃的原有Child Cursor和新生成的Child Cursor。這裡CHILD_NUMBER為1的Child Cursor存儲的執行計划走的是對索引的索引快速全掃描,而CHILD_NUMBER為2的Child Cursor存儲的執行計劃則是走的索引範圍掃描,即它們各自存儲的執行計劃是不相同的,所以此時Oracle不能對它們做Cursor合併。
現在將x的值修改為「SYNONYM」:
LHR@orclasm > EXEC :X :='SYNONYM'; PL/SQL procedure successfully completed. LHR@orclasm > SELECT COUNT(*) FROM T_ACS_20170611_LHR T WHERE T.OBJECT_TYPE=:X; COUNT(*) ---------- 3718 LHR@orclasm > SELECT A.SQL_TEXT, A.SQL_ID,A.VERSION_COUNT,A.EXECUTIONS FROM V$SQLAREA A WHERE A.SQL_TEXT LIKE 'SELECT COUNT(*) FROM T_ACS_20170611_LHR T WHERE T.OBJECT_TYPE=%'; SQL_TEXT SQL_ID VERSION_COUNT EXECUTIONS ---------------------------------------------------------------------------------------- ------------- ------------- ---------- SELECT COUNT(*) FROM T_ACS_20170611_LHR T WHERE T.OBJECT_TYPE=:X bt8tk3f1tnwcf 4 5 LHR@orclasm > SELECT A.SQL_ID,A.CHILD_NUMBER,A.EXECUTIONS,A.BUFFER_GETS,A.IS_BIND_SENSITIVE,A.IS_BIND_AWARE,A.IS_SHAREABLE,A.PLAN_HASH_VALUE FROM V$SQL A WHERE A.SQL_ID='bt8tk3f1tnwcf'; SQL_ID CHILD_NUMBER EXECUTIONS BUFFER_GETS I I I PLAN_HASH_VALUE ------------- ------------ ---------- ----------- - - - --------------- bt8tk3f1tnwcf 0 2 309 Y N N 3002671579 bt8tk3f1tnwcf 1 1 522 Y Y Y 4256744017 bt8tk3f1tnwcf 2 1 16 Y Y N 3002671579 bt8tk3f1tnwcf 3 1 79 Y Y Y 3002671579 LHR@orclasm >
從查詢結果可以看到目標SQL對應的列VERSION_COUNT的值從之前的3變為現在的4,列EXECUTIONS的值為5,說明Oracle在第5次執行目標SQL時依然用的是硬解析。從上述查詢結果可以看到,Oracle此時新生成了一個CHILD_NUMBER為3的Child Cursor,並且把存儲相同執行計劃的CHILD NUMBER為2的原有Child Cursor標記為非共享。
該SQL現在的執行計劃為如下所示:
LHR@orclasm > SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('bt8tk3f1tnwcf',3,'advanced')); PLAN_TABLE_OUTPUT ----------------------------------------------------------------------------- SQL_ID bt8tk3f1tnwcf, child number 3 ------------------------------------- SELECT COUNT(*) FROM T_ACS_20170611_LHR T WHERE T.OBJECT_TYPE=:X Plan hash value: 3002671579 --------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 18 (100)| | | 1 | SORT AGGREGATE | | 1 | 7 | | | |* 2 | INDEX RANGE SCAN| IDX_ACS_OBJID_LHR | 3718 | 26026 | 18 (0)| 00:00:01 | --------------------------------------------------------------------------------------- Query Block Name / Object Alias (identified by operation id): ------------------------------------------------------------- 1 - SEL$1 2 - SEL$1 / T@SEL$1 Outline Data ------------- /*+ BEGIN_OUTLINE_DATA IGNORE_OPTIM_EMBEDDED_HINTS OPTIMIZER_FEATURES_ENABLE('11.2.0.3') DB_VERSION('11.2.0.3') ALL_ROWS OUTLINE_LEAF(@"SEL$1") INDEX(@"SEL$1" "T"@"SEL$1" ("T_ACS_20170611_LHR"."OBJECT_TYPE")) END_OUTLINE_DATA */ Peeked Binds (identified by position): -------------------------------------- 1 - :X (VARCHAR2(30), CSID=852): 'SYNONYM' Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("T"."OBJECT_TYPE"=:X) Column Projection Information (identified by operation id): ----------------------------------------------------------- 1 - (#keys=0) COUNT(*)[22]
從上述顯示內容可以看出,該SQL現在的執行計划走的還是對索引的索引範圍掃描,確實與CHILD_NUMBER為2的原有Child Cursor中存儲的執行計劃相同。注意到「Peeked Binds」部分的內容為「1 – :X (VARCHAR2(30), CSID=852): 'SYNONYM'」,這說明Oracle在硬解析該SQL的過程中確實再次使用了綁定變數窺探,並且做「窺探」這個動作時看到的綁定變數攴的輸入值為「SYNONYM」。
對於上述CHILD_NUMBER為3的Child Cursor,綁定變數X的輸入值為「SYNONYM」時對應的記錄數為3718,表TI的記錄數為78174,將值帶入前面合併後的計算公式:
LHR@orclasm > SELECT ROUND(0.9*(3718/78174),6) low,ROUND(1.1*(3718/78174),6) HIGH FROM DUAL; LOW HIGH ---------- ---------- 0.042805 0.052317 LHR@orclasm > SELECT * FROM V$SQL_CS_SELECTIVITY D WHERE D.SQL_ID='bt8tk3f1tnwcf' ORDER BY CHILD_NUMBER; ADDRESS HASH_VALUE SQL_ID CHILD_NUMBER PREDICATE RANGE_ID LOW HIGH ---------------- ---------- ------------- ------------ ---------------------------------------- ---------- ---------- ---------- 00000000AA2108A8 2207936910 bt8tk3f1tnwcf 1 =X 0 0.711697 0.869852 00000000AA2108A8 2207936910 bt8tk3f1tnwcf 2 =X 0 0.035482 0.043367 00000000AA2108A8 2207936910 bt8tk3f1tnwcf 3 =X 0 0.035482 0.052317 LHR@orclasm > SELECT * FROM V$SQL_CS_STATISTICS D WHERE D.SQL_ID='bt8tk3f1tnwcf' ORDER BY D.CHILD_NUMBER; ADDRESS HASH_VALUE SQL_ID CHILD_NUMBER BIND_SET_HASH_VALUE P EXECUTIONS ROWS_PROCESSED BUFFER_GETS CPU_TIME ---------------- ---------- ------------- ------------ ------------------- - ---------- -------------- ----------- ---------- 00000000AA2108A8 2207936910 bt8tk3f1tnwcf 0 821942781 Y 1 3 54 0 00000000AA2108A8 2207936910 bt8tk3f1tnwcf 1 3197905255 Y 1 61819 522 0 00000000AA2108A8 2207936910 bt8tk3f1tnwcf 2 3279106319 Y 1 3083 16 0 00000000AA2108A8 2207936910 bt8tk3f1tnwcf 3 3683986157 Y 1 3719 79 0
從上述計算結果可以看出,現在CHILD_NUMBER為3的Child Cursor對應的可選擇率範圍為[0.042805,0.052317],根本就不在之前V$SQL_CS_SELECTIVITY中記錄的CHILD NUMBER為1的Child Cursor對應的可選擇率範圍[0.711697,0.869852]之內,也不在CHILD_NUMBER為2的Child Cursor對應的可選擇率範圍[0.035482,0.052317]之內,所以Oracle此時還是得用硬解析。
注意,和之前有所不同的是,現在Oracle就能做cursor合併了。因為現在CHILD_NUMBER為2的原有Child Cursor和CHILD_NUMBER為3的新Child Cursor存儲的執行計劃都是走對索引的索引範圍掃描,即它們各自存儲的執行計劃是相同的,所以此時Oracle就可以對它們做Cursor合併。
Cursor合併的過程也包括對各自所對應的可選擇率範圍的合併,合併的原則就是擴展,即要麼擴展新Child cursor對應的可選擇率範圍的下限,要麼擴展新Child Cursor對應的可選擇率範圍的上限。原有Child Cursor對應的可選擇率範圍是[0.035482,0.052317],新Child Cursor對應的可選擇率範圍為[0.042805,0.052317],而0.035482是小於0.042805的,所以這裡Oracle對新Child Cursor的可選擇率範圍的下限做了擴展,擴展後該Child Cursor對應的可選擇率範圍就變成了[0.035482,0.052317],即從V$SQL_CS_SELECTIVITY查詢出來的CHILD_NUMBER為3的新Child Cursor的可選擇率範圍。
現在將的值修改為「JAVA CLASS」,然後再次執行目標SQL:
LHR@orclasm > EXEC :X :='JAVA CLASS'; PL/SQL procedure successfully completed. LHR@orclasm > SELECT COUNT(*) FROM T_ACS_20170611_LHR T WHERE T.OBJECT_TYPE=:X; COUNT(*) ---------- 2381 LHR@orclasm > SELECT A.SQL_TEXT, A.SQL_ID,A.VERSION_COUNT,A.EXECUTIONS FROM V$SQLAREA A WHERE A.SQL_TEXT LIKE 'SELECT COUNT(*) FROM T_ACS_20170611_LHR T WHERE T.OBJECT_TYPE=%'; SQL_TEXT SQL_ID VERSION_COUNT EXECUTIONS ---------------------------------------------------------------------------------------- ------------- ------------- ---------- SELECT COUNT(*) FROM T_ACS_20170611_LHR T WHERE T.OBJECT_TYPE=:X bt8tk3f1tnwcf 5 6 LHR@orclasm > SELECT A.SQL_ID,A.CHILD_NUMBER,A.EXECUTIONS,A.BUFFER_GETS,A.IS_BIND_SENSITIVE,A.IS_BIND_AWARE,A.IS_SHAREABLE,A.PLAN_HASH_VALUE FROM V$SQL A WHERE A.SQL_ID='bt8tk3f1tnwcf'; SQL_ID CHILD_NUMBER EXECUTIONS BUFFER_GETS I I I PLAN_HASH_VALUE ------------- ------------ ---------- ----------- - - - --------------- bt8tk3f1tnwcf 0 2 309 Y N N 3002671579 bt8tk3f1tnwcf 1 1 522 Y Y Y 4256744017 bt8tk3f1tnwcf 2 1 16 Y Y N 3002671579 bt8tk3f1tnwcf 3 1 79 Y Y N 3002671579 bt8tk3f1tnwcf 4 1 74 Y Y Y 3002671579
從如下查詢結果可以看到目標SQL對應的列VERSION_COUNT的值從之前的4變為了現在的5,列EXECUTIONS的值為6,說明Oracle在第6次執行目標SQL時依然用的是硬解析。從查詢結果可以看到,Oracle此時新生成了一個CHILD_NUMBER為4的Child Cursor,並且把存儲相同執行計劃的CHILD NUMBER為3的原有Child Cursor標記為非共享。
目標SQL現在的執行計劃為如下所示:
LHR@orclasm > SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('bt8tk3f1tnwcf',4,'advanced')); PLAN_TABLE_OUTPUT ---------------------------------------------------------------------------- SQL_ID bt8tk3f1tnwcf, child number 4 ------------------------------------- SELECT COUNT(*) FROM T_ACS_20170611_LHR T WHERE T.OBJECT_TYPE=:X Plan hash value: 3002671579 --------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | --------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 12 (100)| | | 1 | SORT AGGREGATE | | 1 | 7 | | | |* 2 | INDEX RANGE SCAN| IDX_ACS_OBJID_LHR | 2381 | 16667 | 12 (0)| 00:00:01 | --------------------------------------------------------------------------------------- Query Block Name / Object Alias (identified by operation id): ------------------------------------------------------------- 1 - SEL$1 2 - SEL$1 / T@SEL$1 Outline Data ------------- /*+ BEGIN_OUTLINE_DATA IGNORE_OPTIM_EMBEDDED_HINTS OPTIMIZER_FEATURES_ENABLE('11.2.0.3') DB_VERSION('11.2.0.3') ALL_ROWS OUTLINE_LEAF(@"SEL$1") INDEX(@"SEL$1" "T"@"SEL$1" ("T_ACS_20170611_LHR"."OBJECT_TYPE")) END_OUTLINE_DATA */ Peeked Binds (identified by position): -------------------------------------- 1 - :X (VARCHAR2(30), CSID=852): 'JAVA CLASS' Predicate Information (identified by operation id): --------------------------------------------------- 2 - access("T"."OBJECT_TYPE"=:X) Column Projection Information (identified by operation id): ----------------------------------------------------------- 1 - (#keys=0) COUNT(*)[22] 49 rows selected.
從上述顯示內容可以看出,目標SQL現在的執行計划走的還是對索引的索引範圍掃描,確實與CHILD_NUMBER為3的原有Child Cursor中存儲的執行計劃相同。注意,「Peeked Binds」部分的內容為「1 – :X (VARCHAR2(30), CSID=852): 'JAVA CLASS'」,說明Oracle在硬解析上述SQL的過程中確實再次使用了綁定變數窺探,並且做「窺探」這個動作時看到的綁定變數的輸入值為"JAVA CLASS」。
對於上述CHILD_NUMBER為4的Child Cursor,綁定變數X的輸入值為「JAVA CLASS」時對應的記錄數為2381,表TI的記錄數為78174,帶入合併後的計算公式:
LHR@orclasm > SELECT ROUND(0.9*(2381/78174),6) low,ROUND(1.1*(2381/78174),6) HIGH FROM DUAL; LOW HIGH ---------- ---------- 0.027412 0.033503 LHR@orclasm > SELECT * FROM V$SQL_CS_SELECTIVITY D WHERE D.SQL_ID='bt8tk3f1tnwcf' ORDER BY CHILD_NUMBER; ADDRESS HASH_VALUE SQL_ID CHILD_NUMBER PREDICATE RANGE_ID LOW HIGH ---------------- ---------- ------------- ------------ ---------------------------------------- ---------- ---------- ---------- 00000000AA2108A8 2207936910 bt8tk3f1tnwcf 1 =X 0 0.711697 0.869852 00000000AA2108A8 2207936910 bt8tk3f1tnwcf 2 =X 0 0.035482 0.043367 00000000AA2108A8 2207936910 bt8tk3f1tnwcf 3 =X 0 0.035482 0.052317 00000000AA2108A8 2207936910 bt8tk3f1tnwcf 4 =X 0 0.027412 0.052317 LHR@orclasm > SELECT * FROM V$SQL_CS_STATISTICS D WHERE D.SQL_ID='bt8tk3f1tnwcf' ORDER BY D.CHILD_NUMBER; ADDRESS HASH_VALUE SQL_ID CHILD_NUMBER BIND_SET_HASH_VALUE P EXECUTIONS ROWS_PROCESSED BUFFER_GETS CPU_TIME ---------------- ---------- ------------- ------------ ------------------- - ---------- -------------- ----------- ---------- 00000000AA2108A8 2207936910 bt8tk3f1tnwcf 0 821942781 Y 1 3 54 0 00000000AA2108A8 2207936910 bt8tk3f1tnwcf 1 3197905255 Y 1 61819 522 0 00000000AA2108A8 2207936910 bt8tk3f1tnwcf 2 3279106319 Y 1 3083 16 0 00000000AA2108A8 2207936910 bt8tk3f1tnwcf 3 3683986157 Y 1 3719 79 0 00000000AA2108A8 2207936910 bt8tk3f1tnwcf 4 4071504174 Y 1 2382 74 0
從上述計算結果可以看出,現在CHILD_NUMBER為4的Child Cursor對應的可選擇率範圍為[0.027412,0.033503],根本就不在之前V$SQL_CS_SELECTIVITY中記錄的之內,所以Oracle此時還是得用硬解析。和之前一樣,Oracle現在也得做Cursor合併。只不過這次是擴展新Child Cursor對應的可選擇率範圍的上限。CHILD_NUMBER為3的原有Child Cursor對應的可選擇率範圍為[0.035482,0.052317],CHILD_NUMBER為4的新Child Cursor對應的可選擇率範圍為[0.027412,0.033503],而0.052317是大於0.033503的,所以這裡Oracle對新Child Cursor的可選擇率範圍的上限做了擴展,擴展後該Child Cursor對應的可選擇率範圍就變成[0.027412,0.052317]。