Pending Statistics

   Oracle11.2开始,可以使用下面方式搜集统计信息:
      1、搜集统计信息完成后,自动发布(默认方式PUBLISH)
      2、保存新的统计信息,并且待定发布
      以待定方式保存新的统计信息,允许你检验新的统计信息,如果统计信息满足需求,再将其发布。
      为了检查统计信息搜集完成后是否自动发布,使用DBMS_STATS,如下:
      SQL> SELECT DBMS_STATS.GET_PREFS('PUBLISH') PUBLISHFROM DUAL;
      查询结果返回TRUE或FALSE。TRUE表明搜集统计信息完成后自动发布,而FALSE表明搜集统计信息完成后将待定。

提示:
数据库存储发布的统计信息到数据字典视图比如USER_TAB_STATISTICS 和USER_IND_STATISTICS。数据库存储待定的统计信息到视图比如USER_TAB_PENDING_STATS和USER_IND_PENDING_STATS。


      你可以在用户或者表级修改PUBLISH设置。例如,修改用户SH的customers表的PUBLISH设置:
      execdbms_stats.set_table_prefs('SH', 'CUSTOMERS', 'PUBLISH','false');
      随后,当搜集customers表的统计信息,搜集完成后,统计信息将不会自动发布,取而代之的是,数据库存储新搜集的统计信息到USER_TAB_PENDING_STATS。
      缺省情况下,优化器使用存在在数据字典视图中已发布的统计信息。如果希望优化器使用新搜集的待定统计信息,设置初始化参数OPTIMIZER_USE_PENDING_STATISTICS的值为TRUE(缺省值为FALSE),并基于表或者用户运行一个工作负载。
      altersession set optimizer_use_pending_statistics = TRUE;
      当编译sql语句,优化器将使用待定的统计信息替代发布的统计信息。如果待定的统计性能是有效的,可以使用执行下面的语句将它发布:
      Execdbms_stats.publish_pending_stats(null, null);
      你可以为一个特定的数据对象发布待定统计信息。例如,使用下面的语句:
      Execdbms_stats.publish_pending_stats('SH','CUSTOMERS');
      如果你不想发布待定的统计信息,执行下面的语句:
      Execdbms_stats.delete_pending_stats('SH','CUSTOMERS');

      你可以使用函数dbms_stats.export_pending_stats导出待定的统计,导出待定的统计到测试系统,使你可以运行一个完整的工作负责测试新的统计信息。

简单实验如下:
SQL> select * from v$version;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bitProduction
PL/SQL Release 11.2.0.3.0 - Production
CORE      11.2.0.3.0          Production
TNS for Linux: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production

SQL> SELECT DBMS_STATS.GET_PREFS('PUBLISH') PUBLISHFROM DUAL;

PUBLISH
----------------------
TRUE

SQL> show parameteroptimizer_use_pending_statistics

NAME                                                                TYPE              VALUE
------------------------------------ -----------------------------------------
optimizer_use_pending_statistics        boolean        FALSE         
SQL>
SQL> create table wxlun_obj as select * fromdba_objects where rownum<10;

Table created.

SQL> create index ind_obj_type onwxlun_obj(object_type);

Index created.

SQL> execdbms_stats.gather_table_stats('wxlun','wxlun_obj');

PL/SQL procedure successfully completed.

SQL>  select table_name,NUM_ROWSfrom user_tab_statistics where table_name='WXLUN_OBJ';

TABLE_NAME                                            NUM_ROWS
------------------------------ ----------
WXLUN_OBJ                                                            9

SQL> select table_name,NUM_ROWS fromUSER_TAB_PENDING_STATS;

no rows selected

SQL>

SQL> SELECT OBJECT_ID FROM wxlun_obj whereobject_type='TABLE';


Execution Plan
----------------------------------------------------------
Plan hash value: 4094614133

--------------------------------------------------------------------------------------------
| Id  |Operation                                    |Name                | Rows  | Bytes | Cost (%CPU)|Time        |
--------------------------------------------------------------------------------------------
  0 | SELECTSTATEMENT                                                    3 |      30|          (0)| 00:00:01 |
  1 |  TABLEACCESS BY INDEX ROWID|WXLUN_OBJ            3 |      30|          (0)| 00:00:01 |
|*  2 |    INDEXRANGESCAN                  | IND_OBJ_TYPE|        3|                    (0)| 00:00:01 |
--------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

    2 -access("OBJECT_TYPE"='TABLE')


Statistics
----------------------------------------------------------
                  recursive calls
                  db block gets
                  consistent gets
                  physical reads
                  redo size
              597  bytes sent via SQL*Net to client
              519  bytes received via SQL*Net from client
                  SQL*Net roundtrips to/from client
                  sorts (memory)
                  sorts (disk)
                  rows processed

SQL>
多次执行:insert into wxlun_obj select * from dba_objects;

SQL> execdbms_stats.set_table_prefs('wxlun','wxlun_obj','PUBLISH','false');

PL/SQL procedure successfully completed.

SQL> execdbms_stats.gather_table_stats('wxlun','wxlun_obj');

PL/SQL procedure successfully completed.

SQL> select table_name,NUM_ROWS fromuser_tab_statistics where table_name='WXLUN_OBJ';

TABLE_NAME                                            NUM_ROWS
------------------------------ ----------
WXLUN_OBJ                                                                ------user_tab_statistics的统计信息未变

SQL> select table_name,NUM_ROWS fromUSER_TAB_PENDING_STATS;

TABLE_NAME                                            NUM_ROWS
------------------------------ ----------
WXLUN_OBJ                                                1085609      ------WXLUN_OBJ的统计信息放到了USER_TAB_PENDING_STATS
SQL> select count(*) from wxlun_obj;

  COUNT(*)
----------
    1085609

SQL> select count(*) from wxlun_obj whereobject_type='TABLE';

  COUNT(*)
----------
        90964

SQL>
因为wxlun_obj中object_type值为TABLE的数据量太多,按照分析下面的查询应该走全表扫描才合理,但是由于前面的设置,事与愿违:
SQL> SELECT OBJECT_ID FROM wxlun_obj whereobject_type='TABLE';

90964 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 4094614133

--------------------------------------------------------------------------------------------
| Id  |Operation                                    |Name                | Rows  | Bytes | Cost (%CPU)|Time        |
--------------------------------------------------------------------------------------------
  0 | SELECTSTATEMENT                                                    3 |      30|          (0)| 00:00:01 |
  1 |  TABLEACCESS BY INDEX ROWID|WXLUN_OBJ            3 |      30|          (0)| 00:00:01 |
|*  2 |    INDEX RANGESCAN             | IND_OBJ_TYPE|        3|                    (0)| 00:00:01 |
--------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

    2 -access("OBJECT_TYPE"='TABLE')


Statistics
----------------------------------------------------------
                  recursive calls
                  db block gets
          18283  consistent gets
                  physical reads
                  redo size
      1592229  bytes sent via SQL*Net to client
          67223  bytes received via SQL*Net fromclient
            6066  SQL*Net roundtrips to/from client
                  sorts (memory)
                  sorts (disk)
          90964  rows processed

SQL>

SQL> alter session setoptimizer_use_pending_statistics = TRUE;

Session altered.

SQL> set linesize 132
SQL> set autotrace traceonly
SQL> SELECT OBJECT_ID FROM wxlun_obj whereobject_type='TABLE';

90964 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 381774511

-------------------------------------------------------------------------------
| Id  |Operation                |Name          | Rows  | Bytes | Cost (%CPU)|Time        |
-------------------------------------------------------------------------------
  0 | SELECTSTATEMENT                    | 90024 |  1142K|  4148    (1)| 00:00:50 |
|*  1 |  TABLE ACCESS FULL| WXLUN_OBJ | 90024|  1142K|  4148    (1)| 00:00:50 |
-------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

    1 -filter("OBJECT_TYPE"='TABLE')


Statistics
----------------------------------------------------------
                52  recursive calls
                  db block gets
          20656  consistent gets
                  physical reads
                  redo size
      1592229  bytes sent via SQL*Net to client
          67223  bytes received via SQL*Net fromclient
            6066  SQL*Net roundtrips to/from client
                  sorts (memory)
                  sorts (disk)
          90964  rows processed

SQL>

SQL> Execdbms_stats.publish_pending_stats('wxlun','wxlun_obj');


PL/SQL procedure successfully completed.

SQL> select table_name,NUM_ROWS fromuser_tab_statistics where table_name='WXLUN_OBJ';

TABLE_NAME                                            NUM_ROWS
------------------------------ ----------
WXLUN_OBJ                                                1085609

SQL> select table_name,NUM_ROWS fromUSER_TAB_PENDING_STATS;

no rows selected

SQL>
SQL> alter session setoptimizer_use_pending_statistics = false;

Session altered.

SQL> SELECT OBJECT_ID FROM wxlun_obj whereobject_type='TABLE';

90964 rows selected.


Execution Plan
----------------------------------------------------------
Plan hash value: 381774511

-------------------------------------------------------------------------------
| Id  |Operation                |Name          | Rows  | Bytes | Cost (%CPU)|Time        |
-------------------------------------------------------------------------------
  0 | SELECTSTATEMENT                    | 90024 |  1142K|  4148    (1)| 00:00:50 |
|*  1 |  TABLE ACCESS FULL| WXLUN_OBJ | 90024|  1142K|  4148    (1)| 00:00:50 |
-------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

    1 -filter("OBJECT_TYPE"='TABLE')


Statistics
----------------------------------------------------------
                  recursive calls
                  db block gets
          20625  consistent gets
                  physical reads
                  redo size
      1592229  bytes sent via SQL*Net to client
          67223  bytes received via SQL*Net fromclient
            6066  SQL*Net roundtrips to/from client
                  sorts (memory)
                  sorts (disk)
          90964  rows processed

SQL>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值