[20120420]11GR2新特性ACS的使用问题.txt

简介: [20120420]11GR2新特性ACS的使用问题.txt11GR2中采用Adaptive Cursor Sharing一定程度解决了bind peeking的问题。
[20120420]11GR2新特性ACS的使用问题.txt

11GR2中采用Adaptive Cursor Sharing一定程度解决了bind peeking的问题。在我的测试中遇到一些问题,自己写一个例子测试如下:

1.建立测试环境:
SQL> select * from v$version ;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE    11.2.0.1.0      Production
TNS for Linux: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production

SQL> CREATE TABLE t1 AS
SELECT ROWNUM id1,FLOOR(SQRT(ROWNUM)) id2 ,'test' NAME FROM DUAL CONNECT BY LEVEL

SQL> insert into t1 select rownum+9999,100 ,'test' NAME FROM DUAL CONNECT BY LEVEL

SQL> create index i_t1_id2 on t1(id2);
Index created.

BEGIN
  SYS.DBMS_STATS.GATHER_TABLE_STATS (
      OwnName        => user
     ,TabName        => 'T1'
    ,Estimate_Percent  => NULL
    ,Method_Opt        => 'FOR COLUMNS ID2 SIZE 254'
    ,Degree            => 4
    ,Cascade           => TRUE
    ,No_Invalidate     => TRUE);
END;
/

SQL> column low_value format a10
SQL> column high_value format a10
SQL> column data_type format a10
SQL> select column_name,data_type,num_distinct,low_value,high_value,num_buckets,histogram from dba_tab_cols where wner=user and table_name='T1';
COLUMN_NAME                    DATA_TYPE  NUM_DISTINCT LOW_VALUE  HIGH_VALUE NUM_BUCKETS HISTOGRAM
------------------------------ ---------- ------------ ---------- ---------- ----------- ---------------
ID1                            NUMBER            19998 C102       C3026463             1 NONE
ID2                            NUMBER              100 C102       C202               100 FREQUENCY
NAME                           CHAR                  1 74657374   74657374             1 NONE

SQL>

--可以发现ID2建立的直方图是FREQUENCY直方图。

SQL> column ENDPOINT_ACTUAL_VALUE format a10
SQL> column COLUMN_NAME  format a10
SQL> column owner format a10
SQL> column table_name format a10
SQL> select * from dba_tab_histograms where wner=user and table_name='T1' and column_name='ID2';
OWNER      TABLE_NAME COLUMN_NAM ENDPOINT_NUMBER ENDPOINT_VALUE ENDPOINT_A
---------- ---------- ---------- --------------- -------------- ----------
SCOTT      T1         ID2                      3              1
SCOTT      T1         ID2                      8              2
SCOTT      T1         ID2                     15              3
SCOTT      T1         ID2                     24              4
SCOTT      T1         ID2                     35              5
SCOTT      T1         ID2                     48              6
SCOTT      T1         ID2                     63              7
SCOTT      T1         ID2                     80              8
SCOTT      T1         ID2                     99              9
SCOTT      T1         ID2                    120             10
....
SCOTT      T1         ID2                   7920             88
SCOTT      T1         ID2                   8099             89
SCOTT      T1         ID2                   8280             90
SCOTT      T1         ID2                   8463             91
SCOTT      T1         ID2                   8648             92
SCOTT      T1         ID2                   8835             93
SCOTT      T1         ID2                   9024             94
SCOTT      T1         ID2                   9215             95
SCOTT      T1         ID2                   9408             96
SCOTT      T1         ID2                   9603             97
SCOTT      T1         ID2                   9800             98
SCOTT      T1         ID2                   9999             99
SCOTT      T1         ID2                  19998            100

100 rows selected.


2.检查与建立测试脚本,适当编辑一下:
set head off trimout on trimspool on
column a format a100
spool acs.sql
select 'set termout off'  a from dual 
union all
select 'variable a number;' a from dual
union all
select 'exec :a :='||rownum||';'||chr(10)||'select * from t1 where id2= :a;' a from dual connect by level
union all
select 'exec :a :='||'100;' a from  dual
union all
select 'select * from t1 where id2= :a;' a from dual connect by level
union all
select 'set termout on'  a from dual ;

--产生的sql脚本中:a=100的执行了108+1次,其他情况的执行了109次,两种正好相等。
--并且在脚本执行顺序上是最后执行:a := 100的语句执行108次。



3.调用acs.sql并执行它,很明显在:a 100时选择使用索引是最好的执行计划,而等于:a :=100 选择全表扫描最佳。
SQL> host cat dpc.sql
select * from table(dbms_xplan.display_cursor(NULL,NULL,'ALLSTATS LAST PEEKED_BINDS cost'));
SQL> alter system flush shared_pool;
System altered.
SQL> show parameter cursor_sharing
NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------------------------------------
cursor_sharing                       string      EXACT
SQL

SQL> @acs.sql
SQL> @dpc.sql
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  01yvuvyfm4fhb, child number 0
-------------------------------------
select * from t1 where id2= :a
Plan hash value: 3984699272
----------------------------------------------------------------------
| Id  | Operation                   | Name     | E-Rows | Cost (%CPU)|
----------------------------------------------------------------------
|   0 | SELECT STATEMENT            |          |        |     2 (100)|
|   1 |  TABLE ACCESS BY INDEX ROWID| T1       |      3 |     2   (0)|
|*  2 |   INDEX RANGE SCAN          | I_T1_ID2 |      3 |     1   (0)|
----------------------------------------------------------------------
Peeked Binds (identified by position):
--------------------------------------
   1 - (NUMBER): 1
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("ID2"=:A)
Note
-----
   - Warning: basic plan statistics not available. These are only collected when:
       * hint 'gather_plan_statistics' is used for the statement or
       * parameter 'statistics_level' is set to 'ALL', at session or system level
30 rows selected.

--可以发现执行计划还是使用索引.并且知道sql_id='01yvuvyfm4fhb'.

SQL> @ share 01yvuvyfm4fhb
old  15:           and q.sql_id like ''&1''',
new  15:           and q.sql_id like ''01yvuvyfm4fhb''',
SQL_TEXT                       = select * from t1 where id2= :a
SQL_ID                         = 01yvuvyfm4fhb
ADDRESS                        = 00000000997A7898
CHILD_ADDRESS                  = 000000009363BCF0
CHILD_NUMBER                   = 0
LOAD_OPTIMIZER_STATS           = Y
--------------------------------------------------
PL/SQL procedure successfully completed.
--可以发现仅仅存在一个子光标。并没有产生2个光标!

4.查看与ACS有关的试图:
SQL> select * from V$SQL_CS_SELECTIVITY where sql_id='01yvuvyfm4fhb';
no rows selected

SQL> select * from V$SQL_CS_HISTOGRAM where sql_id='01yvuvyfm4fhb';
ADDRESS          HASH_VALUE SQL_ID        CHILD_NUMBER  BUCKET_ID      COUNT
---------------- ---------- ------------- ------------ ---------- ----------
00000000997A7898 2637314571 01yvuvyfm4fhb            0          0        109
00000000997A7898 2637314571 01yvuvyfm4fhb            0          1        109
00000000997A7898 2637314571 01yvuvyfm4fhb            0          2          0

SQL> select * from V$SQL_CS_STATISTICS where sql_id='01yvuvyfm4fhb';
ADDRESS          HASH_VALUE SQL_ID        CHILD_NUMBER BIND_SET_HASH_VALUE P EXECUTIONS ROWS_PROCESSED BUFFER_GETS   CPU_TIME
---------------- ---------- ------------- ------------ ------------------- - ---------- -------------- ----------- ----------
00000000997A7898 2637314571 01yvuvyfm4fhb            0           336594526 N          1          19998         146          0
00000000997A7898 2637314571 01yvuvyfm4fhb            0          2342552567 Y          1              6          71          0
00000000997A7898 2637314571 01yvuvyfm4fhb            0          1237562873 N          1             42           5          0

-- 从V$SQL_CS_HISTOGRAM看sql_id='01yvuvyfm4fhb',蓝色部分都是109次。
--换一句话讲如果在具体应用中如果执行:a :=100的次数不超过其他数据的执行次数,ACS将不会生效。

5.我们再执行一次:a:=100的情况看看。
SQL> exec :a :=100;
PL/SQL procedure successfully completed.
SQL> select * from t1 where id2= :a;
SQL> @dpc
PLAN_TABLE_OUTPUT
-------------------------------------
SQL_ID  01yvuvyfm4fhb, child number 1
-------------------------------------
select * from t1 where id2= :a
Plan hash value: 3617692013
--------------------------------------------------------
| Id  | Operation         | Name | E-Rows | Cost (%CPU)|
--------------------------------------------------------
|   0 | SELECT STATEMENT  |      |        |    16 (100)|
|*  1 |  TABLE ACCESS FULL| T1   |   9999 |    16   (0)|
--------------------------------------------------------
Peeked Binds (identified by position):
--------------------------------------
   1 - (NUMBER): 100
Predicate Information (identified by operation id):
--------------------------------------------------
   1 - filter("ID2"=:A)
Note
-----
   - Warning: basic plan statistics not available. These are only collected when:
       * hint 'gather_plan_statistics' is used for the statement or
       * parameter 'statistics_level' is set to 'ALL', at session or system level
29 rows selected.

--可以发现现在才出现全表扫描的执行计划。

SQL> column sql_text format a30
SQL> column is_obsolete format a10
SQL> column is_bind_aware format a10
SQL> column is_shareable format a10
SQL> column is_bind_aware format a10
SQL> SELECT sql_text, sql_id, child_number,executions, plsql_exec_time, is_obsolete, is_bind_sensitive, is_bind_aware, is_shareable from v$sql where sql_id='01yvuvyfm4fhb';
SQL_TEXT                       SQL_ID        CHILD_NUMBER EXECUTIONS PLSQL_EXEC_TIME IS_OBSOLET I IS_BIND_AW IS_SHAREAB
------------------------------ ------------- ------------ ---------- --------------- ---------- - ---------- ----------
select * from t1 where id2= :a 01yvuvyfm4fhb            0        218               0 N          Y N          Y
select * from t1 where id2= :a 01yvuvyfm4fhb            1          1               0 N          Y Y          Y

SQL> exec :a :=99;
PL/SQL procedure successfully completed.
SQL> select * from t1 where id2= :a;
SQL> @dpc
SQL> @dpc
PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------
SQL_ID  01yvuvyfm4fhb, child number 2
-------------------------------------
select * from t1 where id2= :a
Plan hash value: 3984699272
----------------------------------------------------------------------
| Id  | Operation                   | Name     | E-Rows | Cost (%CPU)|
----------------------------------------------------------------------
|   0 | SELECT STATEMENT            |          |        |     2 (100)|
|   1 |  TABLE ACCESS BY INDEX ROWID| T1       |    199 |     2   (0)|
|*  2 |   INDEX RANGE SCAN          | I_T1_ID2 |    199 |     1   (0)|
----------------------------------------------------------------------
Peeked Binds (identified by position):
--------------------------------------
   1 - (NUMBER): 99
Predicate Information (identified by operation id):
---------------------------------------------------
   2 - access("ID2"=:A)
Note
-----
   - Warning: basic plan statistics not available. These are only collected when:
       * hint 'gather_plan_statistics' is used for the statement or
       * parameter 'statistics_level' is set to 'ALL', at session or system level
30 rows selected.

SQL> SELECT sql_text, sql_id, child_number,executions, plsql_exec_time, is_obsolete, is_bind_sensitive, is_bind_aware, is_shareable from v$sql where sql_id='01yvuvyfm4fhb';
SQL_TEXT                       SQL_ID        CHILD_NUMBER EXECUTIONS PLSQL_EXEC_TIME IS_OBSOLET I IS_BIND_AW IS_SHAREAB
------------------------------ ------------- ------------ ---------- --------------- ---------- - ---------- ----------
select * from t1 where id2= :a 01yvuvyfm4fhb            0        218               0 N          Y N          N
select * from t1 where id2= :a 01yvuvyfm4fhb            1          1               0 N          Y Y          Y
select * from t1 where id2= :a 01yvuvyfm4fhb            2          1               0 N          Y Y          Y

--可以发现child_number=0的is_shareable='N',不再共享。最后将被淘汰出共享池。

6.查看与ACS有关的试图:
SQL> select * from V$SQL_CS_SELECTIVITY where sql_id='01yvuvyfm4fhb';
ADDRESS          HASH_VALUE SQL_ID        CHILD_NUMBER PREDICATE                                  RANGE_ID LOW        HIGH
---------------- ---------- ------------- ------------ ---------------------------------------- ---------- ---------- ----------
00000000997A7898 2637314571 01yvuvyfm4fhb            2 =A                                                0 0.008956   0.010946
00000000997A7898 2637314571 01yvuvyfm4fhb            1 =A                                                0 0.449977   0.549972

SQL> select * from V$SQL_CS_HISTOGRAM where sql_id='01yvuvyfm4fhb';
ADDRESS          HASH_VALUE SQL_ID        CHILD_NUMBER  BUCKET_ID      COUNT
---------------- ---------- ------------- ------------ ---------- ----------
00000000997A7898 2637314571 01yvuvyfm4fhb            2          0          1
00000000997A7898 2637314571 01yvuvyfm4fhb            2          1          0
00000000997A7898 2637314571 01yvuvyfm4fhb            2          2          0
00000000997A7898 2637314571 01yvuvyfm4fhb            1          0          0
00000000997A7898 2637314571 01yvuvyfm4fhb            1          1          1
00000000997A7898 2637314571 01yvuvyfm4fhb            1          2          0
00000000997A7898 2637314571 01yvuvyfm4fhb            0          0        109
00000000997A7898 2637314571 01yvuvyfm4fhb            0          1        109
00000000997A7898 2637314571 01yvuvyfm4fhb            0          2          0

9 rows selected.

SQL> select * from V$SQL_CS_STATISTICS where sql_id='01yvuvyfm4fhb';
ADDRESS          HASH_VALUE SQL_ID        CHILD_NUMBER BIND_SET_HASH_VALUE P EXECUTIONS ROWS_PROCESSED BUFFER_GETS   CPU_TIME
---------------- ---------- ------------- ------------ ------------------- - ---------- -------------- ----------- ----------
00000000997A7898 2637314571 01yvuvyfm4fhb            2          1937997561 Y          1            398           5          0
00000000997A7898 2637314571 01yvuvyfm4fhb            1           336594526 Y          1           9999         103          0
00000000997A7898 2637314571 01yvuvyfm4fhb            0           336594526 N          1          19998         146          0
00000000997A7898 2637314571 01yvuvyfm4fhb            0          2342552567 Y          1              6          71          0
00000000997A7898 2637314571 01yvuvyfm4fhb            0          1237562873 N          1             42           5          0

7.总结:
可以发现ACS在解决bind peeking上依旧存在一定的局限行,要解决它当然有许多方法。也许最好的方法还是加入提示/*+ BIND_AWARE */ .
目录
相关文章
|
15天前
|
存储 关系型数据库 分布式数据库
PostgreSQL 18 发布,快来 PolarDB 尝鲜!
PostgreSQL 18 发布,PolarDB for PostgreSQL 全面兼容。新版本支持异步I/O、UUIDv7、虚拟生成列、逻辑复制增强及OAuth认证,显著提升性能与安全。PolarDB-PG 18 支持存算分离架构,融合海量弹性存储与极致计算性能,搭配丰富插件生态,为企业提供高效、稳定、灵活的云数据库解决方案,助力企业数字化转型如虎添翼!
|
10天前
|
缓存 并行计算 PyTorch
144_推理时延优化:Profiling与瓶颈分析 - 使用PyTorch Profiler诊断推理延迟,优化矩阵运算的独特瓶颈
在2025年的大模型时代,推理时延优化已经成为部署LLM服务的关键挑战之一。随着模型规模的不断扩大(从数亿参数到数千亿甚至万亿参数),即使在最先进的硬件上,推理延迟也常常成为用户体验和系统吞吐量的主要瓶颈。
342 147
|
10天前
|
机器学习/深度学习 存储 缓存
92_自我反思提示:输出迭代优化
在大型语言模型(LLM)应用日益普及的今天,如何持续提升模型输出质量成为了业界关注的核心问题。传统的提示工程方法往往依赖一次性输入输出,难以应对复杂任务中的多轮优化需求。2025年,自我反思提示技术(Self-Reflection Prompting)作为提示工程的前沿方向,正在改变我们与LLM交互的方式。这项技术通过模拟人类的自我反思认知过程,让模型能够对自身输出进行评估、反馈和优化,从而实现输出质量的持续提升。
394 136
|
3天前
|
人工智能 移动开发 自然语言处理
阿里云百炼产品月刊【2025年9月】
本月通义千问模型大升级,新增多模态、语音、视频生成等高性能模型,支持图文理解、端到端视频生成。官网改版上线全新体验中心,推出高代码应用与智能体多模态知识融合,RAG能力增强,助力企业高效部署AI应用。
234 1
|
13天前
|
存储 人工智能 搜索推荐
终身学习型智能体
当前人工智能前沿研究的一个重要方向:构建能够自主学习、调用工具、积累经验的小型智能体(Agent)。 我们可以称这种系统为“终身学习型智能体”或“自适应认知代理”。它的设计理念就是: 不靠庞大的内置知识取胜,而是依靠高效的推理能力 + 动态获取知识的能力 + 经验积累机制。
399 135
|
13天前
|
存储 人工智能 Java
AI 超级智能体全栈项目阶段二:Prompt 优化技巧与学术分析 AI 应用开发实现上下文联系多轮对话
本文讲解 Prompt 基本概念与 10 个优化技巧,结合学术分析 AI 应用的需求分析、设计方案,介绍 Spring AI 中 ChatClient 及 Advisors 的使用。
519 132
AI 超级智能体全栈项目阶段二:Prompt 优化技巧与学术分析 AI 应用开发实现上下文联系多轮对话
|
13天前
|
人工智能 Java API
AI 超级智能体全栈项目阶段一:AI大模型概述、选型、项目初始化以及基于阿里云灵积模型 Qwen-Plus实现模型接入四种方式(SDK/HTTP/SpringAI/langchain4j)
本文介绍AI大模型的核心概念、分类及开发者学习路径,重点讲解如何选择与接入大模型。项目基于Spring Boot,使用阿里云灵积模型(Qwen-Plus),对比SDK、HTTP、Spring AI和LangChain4j四种接入方式,助力开发者高效构建AI应用。
531 122
AI 超级智能体全栈项目阶段一:AI大模型概述、选型、项目初始化以及基于阿里云灵积模型 Qwen-Plus实现模型接入四种方式(SDK/HTTP/SpringAI/langchain4j)