【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]。