• 绑定变量窥探和直方图


    绑定变量窥视cbo的一个附属功能,关闭他不会影响是用cbo还是rbo,就算关闭了绑定变量窥视,cbo还是会利用别的统计信息(num_distinct,density等)来评估cost和cardinality,只
    
    是无法使用直方图信息而已:
    
    
    SQL> SELECT x.ksppinm NAME, y.ksppstvl VALUE, x.ksppdesc describ
     FROM SYS.x$ksppi x, SYS.x$ksppcv y
     WHERE x.inst_id = USERENV ('Instance')
     AND y.inst_id = USERENV ('Instance')
     AND x.indx = y.indx
     AND x.ksppinm LIKE '%&par%';  2    3    4    5    6  
    Enter value for par: peek_user
    old   6:  AND x.ksppinm LIKE '%&par%'
    new   6:  AND x.ksppinm LIKE '%peek_user%'
    
    NAME VALUE DESCRIB
    ------------------------------ -------------------- ------------------------------
    
    _optim_peek_user_binds TRUE enable peeking of user binds
    
    
    当前开启绑定变量,开始测试:
    SQL> alter system flush shared_pool;
    
    System altered.
    
    SQL> select sql_text,sql_id,a.executions from v$sql a 
    where a.parsing_schema_name='SCOTT'
    order by last_active_time desc;  2    3  
    
    no rows selected
    
    
    
    SQL> variable n number; 
    SQL> exec :n := 7499;
    
    PL/SQL procedure successfully completed.
    
    SQL> select * from emp where empno = :n;
    
         EMPNO ENAME      JOB	       MGR HIREDATE	    SAL       COMM
    ---------- ---------- --------- ---------- --------- ---------- ----------
        DEPTNO DNAME
    ---------- --------------------------------------------------
          7499 ALLEN      SALESMAN	      7698 20-FEB-81	   1600        300
    	30 UFO
    
    
    SQL> select sql_text,sql_id,a.executions from v$sql a 
    where a.parsing_schema_name='SCOTT'
    order by last_active_time desc;   2    3  
    
    SQL_TEXT		       SQL_ID	     EXECUTIONS
    ------------------------------ ------------- ----------
    select * from emp where empno  3vv0t64yn0wrm	      1
    = :n
    
    BEGIN :n := 7499; END;	       2u1u06mytpsha	      1
    
    
    SQL> exec :n := 7521;
    
    PL/SQL procedure successfully completed.
    
    SQL> select * from emp where empno = :n;
    
         EMPNO ENAME      JOB	       MGR HIREDATE	    SAL       COMM
    ---------- ---------- --------- ---------- --------- ---------- ----------
        DEPTNO DNAME
    ---------- --------------------------------------------------
          7521 WARD       SALESMAN	      7698 22-FEB-81	   1250        500
    	30 UFO
    
    
    查看执行次数:
    SQL> select sql_text,sql_id,a.executions from v$sql a 
    where a.parsing_schema_name='SCOTT'
    order by last_active_time desc;  2    3  
    
    SQL_TEXT		       SQL_ID	     EXECUTIONS
    ------------------------------ ------------- ----------
    select * from emp where empno  3vv0t64yn0wrm	      2
    = :n
    
    BEGIN :n := 7521; END;	       9b4dm4tp4k58q	      1
    BEGIN :n := 7499; END;	       2u1u06mytpsha	      1
    
    
    此时说明代码完全共享
    
    2.继续测试,关闭绑定变量窥探:
    SQL> SQL>  alter system  set "_optim_peek_user_binds"=FALSE;
    
    System altered.
    
    Session altered.
    SQL> SELECT x.ksppinm NAME, y.ksppstvl VALUE, x.ksppdesc describ
     FROM SYS.x$ksppi x, SYS.x$ksppcv y
     WHERE x.inst_id = USERENV ('Instance')
     AND y.inst_id = USERENV ('Instance')
     AND x.indx = y.indx
     AND x.ksppinm LIKE '%&par%';  2    3    4    5    6  
    Enter value for par: peek_user
    old   6:  AND x.ksppinm LIKE '%&par%'
    new   6:  AND x.ksppinm LIKE '%peek_user%'
    
    NAME
    ----------
    VALUE
    ------------------------------------------------------------------------------------------------------------------------------------------------------------
    
    --------------------------------------------
    DESCRIB
    ------------------------------------------------------------------------------------------------------------------------------------------------------------
    
    --------------------------------------------
    _optim_pee
    k_user_bin
    ds
    FALSE
    enable peeking of user binds
    
    此时绑定变量已经关闭:
    SQL> alter system flush shared_pool;
    
    System altered.
    
    
    SQL> exec :n := 7698;
    
    PL/SQL procedure successfully completed.
    
    SQL> select * from emp where empno = :n;
    
         EMPNO ENAME      JOB	       MGR HIREDATE	    SAL       COMM
    ---------- ---------- --------- ---------- --------- ---------- ----------
        DEPTNO DNAME
    ---------- --------------------------------------------------
          7698 BLAKE      MANAGER	      7839 01-MAY-81	   2850
    	30 UFO
    
    
    SQL> exec :n := 7654;
    
    PL/SQL procedure successfully completed.
    
    SQL> select * from emp where empno = :n;
    
         EMPNO ENAME      JOB	       MGR HIREDATE	    SAL       COMM
    ---------- ---------- --------- ---------- --------- ---------- ----------
        DEPTNO DNAME
    ---------- --------------------------------------------------
          7654 MARTIN     SALESMAN	      7698 28-SEP-81	   1250       1400
    	30 UFO
    
    
    
    查看执行情况:
    SQL> select sql_text,sql_id,a.executions from v$sql a 
    where a.parsing_schema_name='SCOTT'  2  ;
    
    SQL_TEXT		       SQL_ID	     EXECUTIONS
    ------------------------------ ------------- ----------
    select * from emp where empno  3vv0t64yn0wrm	      2
    = :n
    
    BEGIN :n := 7698; END;	       gp8mhcr67r352	      1
    BEGIN :n := 7654; END;	       apkbvs4zq7cnh	      1
    
    SQL> select a.sql_text,a.sql_id,a.executions,a.version_count from v$sqlarea a where sql_id='3vv0t64yn0wrm';
    
    SQL_TEXT		       SQL_ID	     EXECUTIONS VERSION_COUNT
    ------------------------------ ------------- ---------- -------------
    select * from emp where empno  3vv0t64yn0wrm	      3 	    1
    = :n
    
    
    SQL> 
    select a.sql_text,a.sql_id,a.executions,a.child_number from v$sql a where sql_id='3vv0t64yn0wrm';SQL> 
    
    SQL_TEXT		       SQL_ID	     EXECUTIONS CHILD_NUMBER
    ------------------------------ ------------- ---------- ------------
    select * from emp where empno  3vv0t64yn0wrm	      3 	   0
    = :n
    
    说明关闭绑定变量窥探,不会影响SQL语句的共享,关闭绑定变量窥探,Oracle就不能利用直方图信息了。
    
    继续测试关闭绑定变量窥探,对Oracle执行计划的影响?
    
    先打开绑定变量窥探:
    SQL> SELECT x.ksppinm NAME, y.ksppstvl VALUE, x.ksppdesc describ
     FROM SYS.x$ksppi x, SYS.x$ksppcv y
     WHERE x.inst_id = USERENV ('Instance')
     AND y.inst_id = USERENV ('Instance')
     AND x.indx = y.indx
     AND x.ksppinm LIKE '%&par%';  2    3    4    5    6  
    Enter value for par: peek_user
    old   6:  AND x.ksppinm LIKE '%&par%'
    new   6:  AND x.ksppinm LIKE '%peek_user%'
    
    NAME
    --------------------------------------------------------------------------------
    VALUE
    --------------------------------------------------------------------------------
    DESCRIB
    --------------------------------------------------------------------------------
    _optim_peek_user_binds
    TRUE
    enable peeking of user binds
    
    
    SQL> begin
      2  for i in 1 .. 10000
      3  loop
      4  insert into test values(1,'a1'||i);
      5  commit;
      6  end loop; 
      7  end;
      8  /
    
    SQL> insert  into test values(2,'a');
    
    1 row created.
    
    SQL> commit;
    
    Commit complete.
    
    SQL> select id,count(*) from test
      2  group by id;
    
    	ID   COUNT(*)
    ---------- ----------
    	 1	10000
    	 2	    1
    
    
    SQL> BEGIN
      DBMS_STATS.GATHER_TABLE_STATS(ownname          => 'TEST',
                                    tabname          => 'TEST',
                                    estimate_percent => 100,
                                    method_opt       => 'for all columns size skewonly',
                                    no_invalidate    => FALSE,
                                    degree           => 8,
                                    cascade          => TRUE);
    END;
      2    3    4    5    6    7    8    9   10  
     11  /
    
    PL/SQL procedure successfully completed.
    
    SQL> variable n number;
    SQL> exec :n := 2;
    
    PL/SQL procedure successfully completed.
    
    SQL> select * from test where id = :n;
    
    	ID NAME
    ---------- ----------
    	 2 a
    
    SQL> select * from table(dbms_xplan.display_cursor);
    
    PLAN_TABLE_OUTPUT
    ------------------------------------------------------------------------------------------------------------------------------------------------------------
    
    --------------------------------------------
    SQL_ID	14nw6f8vtgsz7, child number 0
    -------------------------------------
    select * from test where id = :n
    
    Plan hash value: 2624864549
    
    -----------------------------------------------------------------------------------------
    | Id  | Operation		    | Name	| Rows	| Bytes | Cost (%CPU)| Time	|
    -----------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT	    |		|	|	|     2 (100)|		|
    |   1 |  TABLE ACCESS BY INDEX ROWID| TEST	|     1 |    14 |     2   (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN	    | TEST_IDX1 |     1 |	|     1   (0)| 00:00:01 |
    -----------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - access("ID"=:N)
    
    
    19 rows selected.
    返回一条记录走的索引扫描
    
    
    
    SQL> exec :n := 1;
    
    PL/SQL procedure successfully completed.
    
    SQL> select * from test where id = :n;
    
    SQL> select * from table(dbms_xplan.display_cursor);
    
    PLAN_TABLE_OUTPUT
    ------------------------------------------------------------------------------------------------------------------------------------------------------------
    
    --------------------------------------------
    SQL_ID	14nw6f8vtgsz7, child number 0
    -------------------------------------
    select * from test where id = :n
    
    Plan hash value: 2624864549
    
    -----------------------------------------------------------------------------------------
    | Id  | Operation		    | Name	| Rows	| Bytes | Cost (%CPU)| Time	|
    -----------------------------------------------------------------------------------------
    |   0 | SELECT STATEMENT	    |		|	|	|     2 (100)|		|
    |   1 |  TABLE ACCESS BY INDEX ROWID| TEST	|     1 |    14 |     2   (0)| 00:00:01 |
    |*  2 |   INDEX RANGE SCAN	    | TEST_IDX1 |     1 |	|     1   (0)| 00:00:01 |
    -----------------------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       2 - access("ID"=:N)
    
    
    19 rows selected.
    
    走的还是索引扫描,充分说明Oracle在处理带有绑定变量的SQL时候,只会在硬解析的时候才会“窥探”一下SQL中绑定变量的值,然后会根据窥探到的值来决定整个SQL的执行计划
    
    。
    
    
    关闭绑定变量窥探:
    
    SQL> alter system  set "_optim_peek_user_binds"=FALSE;
    
    System altered.
    
    SQL> alter system flush shared_pool;
    
    System altered.
    
    SQL> variable n number;
    SQL> exec :n := 2;
    
    PL/SQL procedure successfully completed.
    
    SQL> select * from test where  id = :n;
    
    	ID NAME
    ---------- ----------
    	 2 a
    
    SQL> select * from table(dbms_xplan.display_cursor);
    
    PLAN_TABLE_OUTPUT
    ------------------------------------------------------------------------------------------------------------------------------------------------------------
    
    --------------------------------------------
    SQL_ID	9tcmwpk23vu2y, child number 0
    -------------------------------------
    select * from test where  id = :n
    
    Plan hash value: 1357081020
    
    --------------------------------------------------------------------------
    | Id  | Operation	  | Name | Rows  | Bytes | Cost (%CPU)| Time	 |
    --------------------------------------------------------------------------
    |   0 | SELECT STATEMENT  |	 |	 |	 |     9 (100)| 	 |
    |*  1 |  TABLE ACCESS FULL| TEST |  5001 | 70014 |     9   (0)| 00:00:01 |
    --------------------------------------------------------------------------
    
    Predicate Information (identified by operation id):
    ---------------------------------------------------
    
       1 - filter("ID"=:N)
    
    
    18 rows selected.
    
    此时走了全表扫描,由于关闭了绑定变量窥探,无法利用直方图信息。
    
    
    结论;
      (1)不绑定变量的情况下对于列倾斜严重的情况,直方图可以提供最好的数据分布参考
    
      (2)绑定变量窥视的情况下 可以利用到直方图,但是11g adaptive cursor sharing之前无法区别绑定敏感游标和非敏感游标
    
      (3)不窥视绑定变量的情况下虽然加载直方图信息,但实际计算cardinality不参考HISTOGRAM
    
    
    开始绑定变量:使用直方图信息,然后会根据窥探到的值来决定整个SQL的执行计划。
    
    不开始绑定变量:不使用直方图信息,Oracle不知道数据的分布情况
    
    无论是否开始绑定变量窥探都不影响SQL语句共享
    
    


     

  • 相关阅读:
    配置利用Tilcon 5.8 Radar Demo for vxWorks 6.8
    安装源REMI做源 CentOS上 PHP 的安装和升级
    产品苹果乔布斯和盖茨眼中真实的对方
    平台微软将死的平台:.Net
    企业生活12大颠覆性技术:移动互联网居首
    设备代工富士康加入Firefox OS阵营,下周将发布搭载Firefox OS的设备
    线程对象Android 开发之多线程处理、Handler 详解
    输出hadoop[置顶] hadoop之测试KMeans(二):输出结果分析
    个位数字poj 3126 Prime Path
    nullnullGet previous business day
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13352437.html
Copyright © 2020-2023  润新知