Loading [MathJax]/jax/input/TeX/config.js
首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >【DB笔试面试586】在Oracle中,什么是自适应游标共享(2)?

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

作者头像
AiDBA宝典
发布于 2019-09-29 07:55:19
发布于 2019-09-29 07:55:19
6490
举报

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

代码语言:javascript
AI代码解释
复制
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现在的执行计划如下所示:

代码语言:javascript
AI代码解释
复制
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,带入合并后的计算公式:

代码语言:javascript
AI代码解释
复制
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”:

代码语言:javascript
AI代码解释
复制
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现在的执行计划为如下所示:

代码语言:javascript
AI代码解释
复制
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,将值带入前面合并后的计算公式:

代码语言:javascript
AI代码解释
复制
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:

代码语言:javascript
AI代码解释
复制
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现在的执行计划为如下所示:

代码语言:javascript
AI代码解释
复制
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,带入合并后的计算公式:

代码语言:javascript
AI代码解释
复制
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]。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-06-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DB宝 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【DB笔试面试586】在Oracle中,什么是自适应游标共享(3)?
从如下查询结果可以看到目标SQL对应的列VERSION_COUNT的值从之前的5变为了现在的6,列EXECUTIONS的值为7,说明Oracle在第7次执行目标SQL时依然用的是硬解析。从查询结果可以看到,Oracle此时新生成了一个CHILD_NUMBER为5的Child Cursor,并且把存储相同执行计划的CHILD_NUMBER为4的原有Child Cursor标记为非共享。
AiDBA宝典
2019/09/29
4480
【DB笔试面试586】在Oracle中,什么是自适应游标共享(1)?
绑定变量窥探的副作用就在于,使用了绑定变量的目标SQL只会沿用之前硬解析时所产生的解析树和执行计划,即使这种沿用完全不适合于当前的情形。在Oracle 10g及其后续的版本中,Oracle会自动收集直方图统计信息,这意味着与之前的版本相比,在Oracle 10g及其后续的版本中Oracle有更大的概率会知道目标列实际数据的分布情况,也就是说绑定变量窥探的副作用将会更加明显。当Oracle执行绑定变量窥探操作时绑定变量所对应的输入值是否具有代表性就至关重要了(这里“代表性”是指该输入值所对应的执行计划和该SQL在大多数情况下的执行计划相同),因为这会直接决定此目标SQL在硬解析时所选择的执行计划,进而决定后续以软解析/软软解析重复执行时所沿用的执行计划。
AiDBA宝典
2019/09/29
8550
【DB笔试面试586】在Oracle中,什么是自适应游标共享(4)?
从上述计算结果可以看出,现在计算出的可选择率范围为[0.014172,0.017322],在CHILD_NUMBER为5的原有Child Cursor对应的可选择率范围[0.000023,0.052317]之内,所以刚才Oracle在执行上述SQL时(即第8次执行目标SQL)用的就是软解析/软软解析,并且此时重用的就是CHILD_NUMBER为5的Child Cursor中存储的解析树和执行计划。
AiDBA宝典
2019/09/29
6580
【DB笔试面试582】在Oracle中,什么是绑定变量窥探(下)?
若启用了绑定变量窥探且WHERE条件为“目标列 BETWEEN X AND Y”的selectivity计算公式为:
AiDBA宝典
2019/09/29
1.3K0
【DB笔试面试642】在Oracle中,什么是基数反馈(Cardinality Feedback)?
基数反馈(Cardinality Feedback,CFB)是Oracle 11gR2出现的一个新特性,它的出现是为了帮助Oracle优化器依据更精准的基数生成更加优秀的执行计划。基数的评估准确与否,对于优化器异常重要,直接影响到后续的JOIN COST等重要的成本计算评估。若评估不当则会造成CBO选择不当的执行计划。此技术对于仅执行一次的SQL无效,在SQL第一次执行时,记录存储实际的基数和评估的基数之间的差异,如果差异较大,在第二次执行时,优化器会依据实际的基数重新决策生成执行计划,但是需要注意的是,当使用更准确的基数重新生成执行计划时,生成的执行计划与第一次时使用的执行计划完全有可能是相同的。这个技术的出现是由于优化器在一些情况下不能很好的去计算基数的数值,比如:统计信息缺失或陈旧、多谓词、直方图缺失等等。
AiDBA宝典
2019/09/29
8760
【DB笔试面试582】在Oracle中,什么是绑定变量窥探(上)?
目标SQL若不使用绑定变量,则当具体输入值一旦发生了变化,目标SQL的SQL文本就会随之发生变化,这样Oracle就能很容易地计算出对应Selectivity和Cardinality的值,进而据此来选择执行计划。但对于使用了绑定变量的目标SQL而言,情况就完全不一样了,因为现在无论对应绑定变量的具体输入值是什么,目标SQL的SQL文本都是一模一样的。对于使用了绑定变量的目标SQL而言,Oracle可以选择如下两种方法来决定其执行计划:
AiDBA宝典
2019/09/29
1.8K0
【DB笔试面试580】在Oracle中,什么是High Version Count?
一个父游标下对应的子游标个数被称为Version Count,每个子游标对应一个执行计划。对于一个特定的游标有多少个版本(Version Count)就属于高版本游标是没有明确定义的。对于不同的系统有不同的数量界定。High Version Count不仅产生的原因是多种多样的,而且会导致各种令人头痛的问题,轻则导致数据库的性能急剧下降,CPU利用率剧增,重则导致数据库挂起,触发ORA-04031或者其它BUG导致宕机。
AiDBA宝典
2019/09/29
1.4K0
【DB笔试面试580】在Oracle中,什么是High Version Count?
Oracle自适应共享游标
    自适应游标共享Adaptive Cursor Sharing或扩展的游标共享(Extended Cursor Sharing)是Oracle 11g的新特性之一,主要用于解决以前版 本中由于绑定变量窥探导致SQL语句无法获得最佳执行计划的缺陷,即能够对效率低下的游标(子游标)进行自动识别而选择最佳的执行计划。本 文详细描述了自适应游标共享并给出示例。     有关绑定变量窥探请参考:Oracle 绑定变量窥探
Leshami
2018/08/14
1.1K0
【DB笔试面试646】在Oracle中,什么是基数(Cardinality)和可选择率(Selectivity)?
在Oracle中,什么是基数(Cardinality)和可选择率(Selectivity)?
AiDBA宝典
2019/09/29
9950
【DB笔试面试646】在Oracle中,什么是基数(Cardinality)和可选择率(Selectivity)?
【DB笔试面试583】在Oracle中,什么是绑定变量分级?
绑定变量分级(Bind Graduation)是指Oracle在PL/SQL代码中会根据文本型绑定变量的定义长度而将这些文本型绑定变量分为四个等级,不同等级分配的内存大小不同,如下表所示:
AiDBA宝典
2019/09/29
9000
【DB笔试面试628】Oracle的统计信息包括哪几种类型?
Oracle数据库里的统计信息是一组存储在数据字典里,且从多个维度描述了数据库里对象的详细信息的一组数据。当Oracle数据库工作在CBO(Cost Based Optimization,基于代价的优化器)模式下时,优化器会根据数据字典中记录的对象的统计信息来评估SQL语句的不同执行计划的成本,从而找到最优或者是相对最优的执行计划。所以,可以说,SQL语句的执行计划由统计信息来决定,若没有统计信息则会采取动态采样的方式来生成执行计划。统计信息决定着SQL的执行计划的正确性,属于SQL执行的指导思想。若统计信息不准确,则会导致表的访问方式(例如应该使用索引,但是选择了全表扫描)、表与表的连接方式出现问题(例如应该使用HJ,但是使用了NL连接),从而导致CBO选择错误的执行计划。
AiDBA宝典
2019/09/29
8340
【DB笔试面试628】Oracle的统计信息包括哪几种类型?
什么是Oracle的高版本游标(High Version Count)?如何排查?(持续更新)
一个父游标下对应的子游标个数被称为Version Count,每个子游标对应一个执行计划。对于一个特定的游标有多少个版本(Version Count)就属于高版本游标是没有明确定义的。对于不同的系统有不同的数量界定。High Version Count不仅产生的原因是多种多样的,而且会导致各种令人头痛的问题,轻则导致数据库的性能急剧下降,CPU利用率剧增,重则导致数据库挂起,触发ORA-04031或者其它BUG导致宕机。
AiDBA宝典
2024/04/18
1.2K0
什么是Oracle的高版本游标(High Version Count)?如何排查?(持续更新)
【DB笔试面试598】在Oracle中,如何得到真实的执行计划?
在Oracle数据库中判断得到的执行计划是否准确,就是看目标SQL是否被真正执行过,真正执行过的SQL所对应的执行计划就是准确的,反之则有可能不准,因此,通过10046事件及如下的几种方式得到的执行计划是最准确的,而从其它方式获取到的执行计划都有可能不准确。
AiDBA宝典
2019/09/29
9030
【DB笔试面试585】在Oracle中,什么是常规游标共享?
游标共享(Cursor Sharing)是指共享游标(Shared Cursor)之间的共享,游标共享可以实现重用存储在子游标(Child Cursor)中的解析树和执行计划而不用从头开始做硬解析,从而提高系统性能。特别对于同一类型的目标SQL更应该实现游标共享,而使用绑定变量就可以实现游标共享。
AiDBA宝典
2019/09/29
1.1K0
【DB笔试面试597】在Oracle中,获取执行计划有哪几种方法?
AUTOTRACE是Oracle自带的客户端工具SQL*Plus的一个特性。启用AUTOTRACE后,SQL*Plus会自动收集执行过的SQL语句的执行计划、性能统计数据等,并在语句执行结束后显示在SQL*Plus中。
AiDBA宝典
2019/09/29
7970
【DB笔试面试597】在Oracle中,获取执行计划有哪几种方法?
【DB笔试面试639】在Oracle中,什么是多列统计信息(Extended Statistics)?
Oracle优化器对于基数值的估算是否准确关系到能否生成最优的执行计划,而基数值估算的准确性又取决于SQL中各个对象的统计信息是否完整、是否能真实反映出对象的数据分布情况。因此使用何种方法收集统计信息是很有讲究的:对于数据倾斜度较大的表需要收集直方图,在此基础上如果有多个列存在相关性,那么多列统计信息(也叫扩展统计信息)收集又是一个更好的选择。
AiDBA宝典
2019/09/29
2.9K0
【DB笔试面试258】在Oracle中,执行计划里的access和filter有什么区别(上)?
一般而言,access表示这个谓词条件的值将会影响数据的访问路径(表还是索引);filter表示谓词条件的值不会影响数据的访问路劲,只起到过滤的作用。NOT IN或MIN函数等容易产生filter操作。
AiDBA宝典
2019/09/30
1.7K0
【DB笔试面试258】在Oracle中,执行计划里的access和filter有什么区别(上)?
【DB笔试面试631】在Oracle中,什么是动态采样(Dynamic Sampling)?
对于没有收集统计信息的表,Oracle为了能够得到相对准确的执行计划,会在执行SQL之前对SQL语句涉及到的表做动态采样(Dynamic Sampling,从Oracle 11.2.0.4开始称之为Dynamic Statistic)。
AiDBA宝典
2019/09/29
7130
【DB笔试面试631】在Oracle中,什么是动态采样(Dynamic Sampling)?
【DB笔试面试593】在Oracle中,表的访问方式有哪几种?
访问表的方式也叫优化器访问路径,主要有3种访问路径:全表扫描(FULL TABLE SCAN,FTS)、索引扫描(INDEX SCAN)和ROWID访问。
AiDBA宝典
2019/09/29
1.5K0
【DB笔试面试593】在Oracle中,表的访问方式有哪几种?
Oracle面对“数据倾斜列使用绑定变量”场景的解决方案
    我们知道,Oracle在传统的OLTP(在线事务处理)类系统中,强烈推荐使用绑定变量,这样可以有效的减少硬解析从而增加系统的并发处理能力。甚至在有些老旧系统,由于在开始开发阶段缺乏认识没有使用到绑定变量,后期并发量增长且无法改造程序时,运维DBA还会不得已去设置cursor_sharing=force来强制使用系统的绑定变量(这是一个万不得已的方案,并不是最佳实践)。
Alfred Zhao
2019/08/27
2.1K0
推荐阅读
【DB笔试面试586】在Oracle中,什么是自适应游标共享(3)?
4480
【DB笔试面试586】在Oracle中,什么是自适应游标共享(1)?
8550
【DB笔试面试586】在Oracle中,什么是自适应游标共享(4)?
6580
【DB笔试面试582】在Oracle中,什么是绑定变量窥探(下)?
1.3K0
【DB笔试面试642】在Oracle中,什么是基数反馈(Cardinality Feedback)?
8760
【DB笔试面试582】在Oracle中,什么是绑定变量窥探(上)?
1.8K0
【DB笔试面试580】在Oracle中,什么是High Version Count?
1.4K0
Oracle自适应共享游标
1.1K0
【DB笔试面试646】在Oracle中,什么是基数(Cardinality)和可选择率(Selectivity)?
9950
【DB笔试面试583】在Oracle中,什么是绑定变量分级?
9000
【DB笔试面试628】Oracle的统计信息包括哪几种类型?
8340
什么是Oracle的高版本游标(High Version Count)?如何排查?(持续更新)
1.2K0
【DB笔试面试598】在Oracle中,如何得到真实的执行计划?
9030
【DB笔试面试585】在Oracle中,什么是常规游标共享?
1.1K0
【DB笔试面试597】在Oracle中,获取执行计划有哪几种方法?
7970
【DB笔试面试639】在Oracle中,什么是多列统计信息(Extended Statistics)?
2.9K0
【DB笔试面试258】在Oracle中,执行计划里的access和filter有什么区别(上)?
1.7K0
【DB笔试面试631】在Oracle中,什么是动态采样(Dynamic Sampling)?
7130
【DB笔试面试593】在Oracle中,表的访问方式有哪几种?
1.5K0
Oracle面对“数据倾斜列使用绑定变量”场景的解决方案
2.1K0
相关推荐
【DB笔试面试586】在Oracle中,什么是自适应游标共享(3)?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
首页
学习
活动
专区
圈层
工具
MCP广场
首页
学习
活动
专区
圈层
工具
MCP广场