【DB笔试面试586】在Oracle中,什么是自适应游标共享(2)?

2021/4/15 2:28:10

本文主要是介绍【DB笔试面试586】在Oracle中,什么是自适应游标共享(2)?,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

另外,在目标列有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带入上述合并后的计算公式:

 1LHR@orclasm > SELECT d.NUM_ROWS FROM dba_tables d WHERE d.TABLE_NAME='T_ACS_20170611_LHR';
 NUM_ROWS
 4----------

 6LHR@orclasm > SELECT ROUND(0.9*(61818/78174),6) low,ROUND(1.1*(61818/78174),6) HIGH FROM DUAL;
      LOW       HIGH
 9---------- ----------
 0.711697    0.869852

12--从上述计算结果可以看出,可选择率范围和之前从VSSQL_CS_SELECTIVITY中查到的结果完全一致。
13--现在将X的值修改为“INDEX”:
14LHR@orclasm > EXEC :X :='INDEX';

16PL/SQL procedure successfully completed.

18LHR@orclasm > SELECT COUNT(*) FROM T_ACS_20170611_LHR T WHERE T.OBJECT_TYPE=:X;
 COUNT(*)
21----------


24LHR@orclasm > 
25LHR@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=%';

27SQL_TEXT                                                                                 SQL_ID        VERSION_COUNT EXECUTIONS
28---------------------------------------------------------------------------------------- ------------- ------------- ----------
29SELECT COUNT(*) FROM T_ACS_20170611_LHR T WHERE T.OBJECT_TYPE=:X                         bt8tk3f1tnwcf             3          4
30LHR@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';

32SQL_ID        CHILD_NUMBER EXECUTIONS BUFFER_GETS I I I PLAN_HASH_VALUE
33------------- ------------ ---------- ----------- - - - ---------------
34bt8tk3f1tnwcf            0          2         309 Y N N      3002671579
35bt8tk3f1tnwcf            1          1         522 Y Y Y      4256744017
36bt8tk3f1tnwcf            2          1          16 Y Y Y      3002671579

38LHR@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现在的执行计划如下所示:

 1LHR@orclasm > SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('bt8tk3f1tnwcf',2,'advanced'));

 3PLAN_TABLE_OUTPUT
 4---------------------------------------------------------------------------------------
 5SQL_ID  bt8tk3f1tnwcf, child number 2
 6-------------------------------------
 7SELECT COUNT(*) FROM T_ACS_20170611_LHR T WHERE T.OBJECT_TYPE=:X

 9Plan hash value: 3002671579

11---------------------------------------------------------------------------------------
12| Id  | Operation         | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
13---------------------------------------------------------------------------------------
14|   0 | SELECT STATEMENT  |                   |       |       |    15 (100)|          |
15|   1 |  SORT AGGREGATE   |                   |     1 |     7 |            |          |
16|*  2 |   INDEX RANGE SCAN| IDX_ACS_OBJID_LHR |  3082 | 21574 |    15   (0)| 00:00:01 |
17---------------------------------------------------------------------------------------

19Query Block Name / Object Alias (identified by operation id):
20-------------------------------------------------------------
  1 - SEL$1
- SEL$1 / T@SEL$1

25Outline Data
26-------------
 /*+
     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
 */

39Peeked Binds (identified by position):
40--------------------------------------
  1 - :X (VARCHAR2(30), CSID=852): 'INDEX'

44Predicate Information (identified by operation id):
45---------------------------------------------------
  2 - access("T"."OBJECT_TYPE"=:X)

49Column Projection Information (identified by operation id):
50-----------------------------------------------------------
  1 - (#keys=0) COUNT(*)[22]

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,带入合并后的计算公式:

 1LHR@orclasm > SELECT ROUND(0.9*(3082/78174),6) low,ROUND(1.1*(3082/78174),6) HIGH FROM DUAL;
      LOW       HIGH
 4---------- ----------
 0.035482    0.043367
 6LHR@orclasm > SELECT * FROM V$SQL_CS_SELECTIVITY D WHERE D.SQL_ID='bt8tk3f1tnwcf' ORDER BY CHILD_NUMBER; 

 8ADDRESS          HASH_VALUE SQL_ID        CHILD_NUMBER PREDICATE                                  RANGE_ID LOW        HIGH
 9---------------- ---------- ------------- ------------ ---------------------------------------- ---------- ---------- ----------
1000000000AA2108A8 2207936910 bt8tk3f1tnwcf            1 =X                                                0 0.711697   0.869852
1100000000AA2108A8 2207936910 bt8tk3f1tnwcf            2 =X                                                0 0.035482   0.043367

14LHR@orclasm > SELECT * FROM V$SQL_CS_STATISTICS D WHERE D.SQL_ID='bt8tk3f1tnwcf' ORDER BY D.CHILD_NUMBER;

16ADDRESS          HASH_VALUE SQL_ID        CHILD_NUMBER BIND_SET_HASH_VALUE P EXECUTIONS ROWS_PROCESSED BUFFER_GETS   CPU_TIME
17---------------- ---------- ------------- ------------ ------------------- - ---------- -------------- ----------- ----------
1800000000AA2108A8 2207936910 bt8tk3f1tnwcf            0           821942781 Y          1              3          54          0
1900000000AA2108A8 2207936910 bt8tk3f1tnwcf            1          3197905255 Y          1          61819         522          0
2000000000AA2108A8 2207936910 bt8tk3f1tnwcf            2          3279106319 Y          1           3083          16          0

22LHR@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”:

 1LHR@orclasm > EXEC :X :='SYNONYM';

 3PL/SQL procedure successfully completed.

 5LHR@orclasm > SELECT COUNT(*) FROM T_ACS_20170611_LHR T WHERE T.OBJECT_TYPE=:X;
 COUNT(*)
 8----------


11LHR@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=%';

13SQL_TEXT                                                                                 SQL_ID        VERSION_COUNT EXECUTIONS
14---------------------------------------------------------------------------------------- ------------- ------------- ----------
15SELECT COUNT(*) FROM T_ACS_20170611_LHR T WHERE T.OBJECT_TYPE=:X                         bt8tk3f1tnwcf             4          5

17LHR@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';

19SQL_ID        CHILD_NUMBER EXECUTIONS BUFFER_GETS I I I PLAN_HASH_VALUE
20------------- ------------ ---------- ----------- - - - ---------------
21bt8tk3f1tnwcf            0          2         309 Y N N      3002671579
22bt8tk3f1tnwcf            1          1         522 Y Y Y      4256744017
23bt8tk3f1tnwcf            2          1          16 Y Y N      3002671579
24bt8tk3f1tnwcf            3          1          79 Y Y Y      3002671579

26LHR@orclasm > 

从查询结果可以看到目标SQL对应的列VERSION_COUNT的值从之前的3变为现在的4,列EXECUTIONS的值为5,说明Oracle在第5次执行目标SQL时依然用的是硬解析。从上述查询结果可以看到,Oracle此时新生成了一个CHILD_NUMBER为3的Child Cursor,并且把存储相同执行计划的CHILD NUMBER为2的原有Child Cursor标记为非共享。

该SQL现在的执行计划为如下所示:

 1LHR@orclasm > SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('bt8tk3f1tnwcf',3,'advanced'));

 3PLAN_TABLE_OUTPUT
 4-----------------------------------------------------------------------------
 5SQL_ID  bt8tk3f1tnwcf, child number 3
 6-------------------------------------
 7SELECT COUNT(*) FROM T_ACS_20170611_LHR T WHERE T.OBJECT_TYPE=:X

 9Plan hash value: 3002671579

11---------------------------------------------------------------------------------------
12| Id  | Operation         | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
13---------------------------------------------------------------------------------------
14|   0 | SELECT STATEMENT  |                   |       |       |    18 (100)|          |
15|   1 |  SORT AGGREGATE   |                   |     1 |     7 |            |          |
16|*  2 |   INDEX RANGE SCAN| IDX_ACS_OBJID_LHR |  3718 | 26026 |    18   (0)| 00:00:01 |
17---------------------------------------------------------------------------------------

19Query Block Name / Object Alias (identified by operation id):
20-------------------------------------------------------------
  1 - SEL$1
- SEL$1 / T@SEL$1

25Outline Data
26-------------
 /*+
     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
 */

39Peeked Binds (identified by position):
40--------------------------------------
  1 - :X (VARCHAR2(30), CSID=852): 'SYNONYM'

44Predicate Information (identified by operation id):
45---------------------------------------------------
  2 - access("T"."OBJECT_TYPE"=:X)

49Column Projection Information (identified by operation id):
50-----------------------------------------------------------
  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,将值带入前面合并后的计算公式:

 1LHR@orclasm > SELECT ROUND(0.9*(3718/78174),6) low,ROUND(1.1*(3718/78174),6) HIGH FROM DUAL;
      LOW       HIGH
 4---------- ----------
 0.042805    0.052317

 7LHR@orclasm > SELECT * FROM V$SQL_CS_SELECTIVITY D WHERE D.SQL_ID='bt8tk3f1tnwcf' ORDER BY CHILD_NUMBER; 

 9ADDRESS          HASH_VALUE SQL_ID        CHILD_NUMBER PREDICATE                                  RANGE_ID LOW        HIGH
10---------------- ---------- ------------- ------------ ---------------------------------------- ---------- ---------- ----------
1100000000AA2108A8 2207936910 bt8tk3f1tnwcf            1 =X                                                0 0.711697   0.869852
1200000000AA2108A8 2207936910 bt8tk3f1tnwcf            2 =X                                                0 0.035482   0.043367
1300000000AA2108A8 2207936910 bt8tk3f1tnwcf            3 =X                                                0 0.035482   0.052317

15LHR@orclasm > SELECT * FROM V$SQL_CS_STATISTICS D WHERE D.SQL_ID='bt8tk3f1tnwcf' ORDER BY D.CHILD_NUMBER;

17ADDRESS          HASH_VALUE SQL_ID        CHILD_NUMBER BIND_SET_HASH_VALUE P EXECUTIONS ROWS_PROCESSED BUFFER_GETS   CPU_TIME
18---------------- ---------- ------------- ------------ ------------------- - ---------- -------------- ----------- ----------
1900000000AA2108A8 2207936910 bt8tk3f1tnwcf            0           821942781 Y          1              3          54          0
2000000000AA2108A8 2207936910 bt8tk3f1tnwcf            1          3197905255 Y          1          61819         522          0
2100000000AA2108A8 2207936910 bt8tk3f1tnwcf            2          3279106319 Y          1           3083          16          0
2200000000AA2108A8 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:

 1LHR@orclasm > EXEC :X :='JAVA CLASS';

 3PL/SQL procedure successfully completed.

 5LHR@orclasm > SELECT COUNT(*) FROM T_ACS_20170611_LHR T WHERE T.OBJECT_TYPE=:X;
 COUNT(*)
 8----------


11LHR@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=%';

13SQL_TEXT                                                                                 SQL_ID        VERSION_COUNT EXECUTIONS
14---------------------------------------------------------------------------------------- ------------- ------------- ----------
15SELECT COUNT(*) FROM T_ACS_20170611_LHR T WHERE T.OBJECT_TYPE=:X                         bt8tk3f1tnwcf             5          6

17LHR@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';

19SQL_ID        CHILD_NUMBER EXECUTIONS BUFFER_GETS I I I PLAN_HASH_VALUE
20------------- ------------ ---------- ----------- - - - ---------------
21bt8tk3f1tnwcf            0          2         309 Y N N      3002671579
22bt8tk3f1tnwcf            1          1         522 Y Y Y      4256744017
23bt8tk3f1tnwcf            2          1          16 Y Y N      3002671579
24bt8tk3f1tnwcf            3          1          79 Y Y N      3002671579
25bt8tk3f1tnwcf            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现在的执行计划为如下所示:

 1LHR@orclasm > SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR('bt8tk3f1tnwcf',4,'advanced'));

 3PLAN_TABLE_OUTPUT
 4----------------------------------------------------------------------------
 5SQL_ID  bt8tk3f1tnwcf, child number 4
 6-------------------------------------
 7SELECT COUNT(*) FROM T_ACS_20170611_LHR T WHERE T.OBJECT_TYPE=:X

 9Plan hash value: 3002671579

11---------------------------------------------------------------------------------------
12| Id  | Operation         | Name              | Rows  | Bytes | Cost (%CPU)| Time     |
13---------------------------------------------------------------------------------------
14|   0 | SELECT STATEMENT  |                   |       |       |    12 (100)|          |
15|   1 |  SORT AGGREGATE   |                   |     1 |     7 |            |          |
16|*  2 |   INDEX RANGE SCAN| IDX_ACS_OBJID_LHR |  2381 | 16667 |    12   (0)| 00:00:01 |
17---------------------------------------------------------------------------------------

19Query Block Name / Object Alias (identified by operation id):
20-------------------------------------------------------------
  1 - SEL$1
- SEL$1 / T@SEL$1

25Outline Data
26-------------
 /*+
     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
 */

39Peeked Binds (identified by position):
40--------------------------------------
  1 - :X (VARCHAR2(30), CSID=852): 'JAVA CLASS'

44Predicate Information (identified by operation id):
45---------------------------------------------------
  2 - access("T"."OBJECT_TYPE"=:X)

49Column Projection Information (identified by operation id):
50-----------------------------------------------------------
  1 - (#keys=0) COUNT(*)[22]

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,带入合并后的计算公式:

 1LHR@orclasm > SELECT ROUND(0.9*(2381/78174),6) low,ROUND(1.1*(2381/78174),6) HIGH FROM DUAL; 
      LOW       HIGH
 4---------- ----------
 0.027412    0.033503

 7LHR@orclasm > SELECT * FROM V$SQL_CS_SELECTIVITY D WHERE D.SQL_ID='bt8tk3f1tnwcf' ORDER BY CHILD_NUMBER; 

 9ADDRESS          HASH_VALUE SQL_ID        CHILD_NUMBER PREDICATE                                  RANGE_ID LOW        HIGH
10---------------- ---------- ------------- ------------ ---------------------------------------- ---------- ---------- ----------
1100000000AA2108A8 2207936910 bt8tk3f1tnwcf            1 =X                                                0 0.711697   0.869852
1200000000AA2108A8 2207936910 bt8tk3f1tnwcf            2 =X                                                0 0.035482   0.043367
1300000000AA2108A8 2207936910 bt8tk3f1tnwcf            3 =X                                                0 0.035482   0.052317
1400000000AA2108A8 2207936910 bt8tk3f1tnwcf            4 =X                                                0 0.027412   0.052317

16LHR@orclasm > SELECT * FROM V$SQL_CS_STATISTICS D WHERE D.SQL_ID='bt8tk3f1tnwcf' ORDER BY D.CHILD_NUMBER;

18ADDRESS          HASH_VALUE SQL_ID        CHILD_NUMBER BIND_SET_HASH_VALUE P EXECUTIONS ROWS_PROCESSED BUFFER_GETS   CPU_TIME
19---------------- ---------- ------------- ------------ ------------------- - ---------- -------------- ----------- ----------
2000000000AA2108A8 2207936910 bt8tk3f1tnwcf            0           821942781 Y          1              3          54          0
2100000000AA2108A8 2207936910 bt8tk3f1tnwcf            1          3197905255 Y          1          61819         522          0
2200000000AA2108A8 2207936910 bt8tk3f1tnwcf            2          3279106319 Y          1           3083          16          0
2300000000AA2108A8 2207936910 bt8tk3f1tnwcf            3          3683986157 Y          1           3719          79          0
2400000000AA2108A8 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]。



本文分享自微信公众号 - DB宝(lhrdba)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。



这篇关于【DB笔试面试586】在Oracle中,什么是自适应游标共享(2)?的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程