暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle可以自动收集GTT的会话特定统计信息吗?

askTom 2018-02-16
317

问题描述

嗨,团队,

首先,非常感谢您所做的所有出色工作!如果您可以帮助我进行查询,那就太好了。

在查看SQL的AWRSQL报告时,我注意到会话特定的统计信息用于该执行。此SQL是update语句,仅涉及单个GTT。

我们没有在代码中明确收集统计信息。令人怀疑的是,Oracle本身是否在执行前收集了特定于会话的统计数据?如果是这样,那么有没有办法让Oracle更频繁地这样做?除此实例外,对于我们,Oracle会自动进行动态采样。这是我第一次看到Oracle自动使用会话特定的统计信息。

创建GTT是为了在提交时保留行,GLOBAL_TEMP_TABLE_STATS保留默认值。高级程序的流程是:

1.通过从其他常规和GTT表中进行选择,将数据插入GTT。在此步骤中插入的行数从6000行到300万行不等。
2.使用仅涉及GTT的Update语句更新插入的数据这次更新也使用了一些聚合函数。

我尝试过,但无法在测试环境中复制此内容。我认为一个不错的选择是在步骤1之后修改流程以收集特定于会话的统计信息。但是,我们无权编辑代码。

谢谢你的帮助。

专家解答

如果数据是通过直接加载加载的,那么加载时的统计信息的标准集合就像普通表一样执行,例如

SQL> create global temporary table T ( x int )
  2  on commit preserve rows;

Table created.

SQL> insert /*+ append */ into t
  2  select rownum
  3  from dual
  4  connect by level <= 1000;

1000 rows created.

SQL>
SQL> select * from table(dbms_xplan.display_cursor);

PLAN_TABLE_OUTPUT
----------------------------------------------------------------------------------
SQL_ID  1bshr3t6jtv86, child number 0
-------------------------------------
insert /*+ append */ into t select rownum from dual connect by level <=
1000

Plan hash value: 1600317434

---------------------------------------------------------------------------------
| Id  | Operation                        | Name | Rows  | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------
|   0 | INSERT STATEMENT                 |      |       |     2 (100)|          |
|   1 |  LOAD AS SELECT                  | T    |       |            |          |
|   2 |   OPTIMIZER STATISTICS GATHERING |      |     1 |     2   (0)| 00:00:01 |  <<======
|   3 |    COUNT                         |      |       |            |          |
|   4 |     CONNECT BY WITHOUT FILTERING |      |       |            |          |
|   5 |      FAST DUAL                   |      |     1 |     2   (0)| 00:00:01 |
---------------------------------------------------------------------------------



而常规的行负载不会

SQL> create global temporary table T ( x int )
  2  on commit preserve rows;

Table created.

SQL>
SQL> insert into t
  2  select rownum
  3  from dual
  4  connect by level <= 1000;

1000 rows created.

SQL>
SQL> select * from table(dbms_xplan.display_cursor);

PLAN_TABLE_OUTPUT
---------------------------------------------------------------------------------
SQL_ID  2th1j5m01vax7, child number 0
-------------------------------------
insert into t select rownum from dual connect by level <= 1000

Plan hash value: 1731520519

-------------------------------------------------------------------------------
| Id  | Operation                      | Name | Rows  | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------
|   0 | INSERT STATEMENT               |      |       |     2 (100)|          |
|   1 |  LOAD TABLE CONVENTIONAL       | T    |       |            |          |
|   2 |   COUNT                        |      |       |            |          |
|   3 |    CONNECT BY WITHOUT FILTERING|      |       |            |          |
|   4 |     FAST DUAL                  |      |     1 |     2   (0)| 00:00:01 |
-------------------------------------------------------------------------------


这可以解释为什么即使没有明确的dbms_stats调用,您也会获得统计数据。

不幸的是,如果要执行更频繁的统计信息收集,则需要使用自己的dbms_stats调用拦截代码。另一种选择是禁用会话统计信息,并完全依赖动态采样。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论