问题描述
嗨,团队,
首先,非常感谢您所做的所有出色工作!如果您可以帮助我进行查询,那就太好了。
在查看SQL的AWRSQL报告时,我注意到会话特定的统计信息用于该执行。此SQL是update语句,仅涉及单个GTT。
我们没有在代码中明确收集统计信息。令人怀疑的是,Oracle本身是否在执行前收集了特定于会话的统计数据?如果是这样,那么有没有办法让Oracle更频繁地这样做?除此实例外,对于我们,Oracle会自动进行动态采样。这是我第一次看到Oracle自动使用会话特定的统计信息。
创建GTT是为了在提交时保留行,GLOBAL_TEMP_TABLE_STATS保留默认值。高级程序的流程是:
1.通过从其他常规和GTT表中进行选择,将数据插入GTT。在此步骤中插入的行数从6000行到300万行不等。
2.使用仅涉及GTT的Update语句更新插入的数据这次更新也使用了一些聚合函数。
我尝试过,但无法在测试环境中复制此内容。我认为一个不错的选择是在步骤1之后修改流程以收集特定于会话的统计信息。但是,我们无权编辑代码。
谢谢你的帮助。
首先,非常感谢您所做的所有出色工作!如果您可以帮助我进行查询,那就太好了。
在查看SQL的AWRSQL报告时,我注意到会话特定的统计信息用于该执行。此SQL是update语句,仅涉及单个GTT。
我们没有在代码中明确收集统计信息。令人怀疑的是,Oracle本身是否在执行前收集了特定于会话的统计数据?如果是这样,那么有没有办法让Oracle更频繁地这样做?除此实例外,对于我们,Oracle会自动进行动态采样。这是我第一次看到Oracle自动使用会话特定的统计信息。
创建GTT是为了在提交时保留行,GLOBAL_TEMP_TABLE_STATS保留默认值。高级程序的流程是:
1.通过从其他常规和GTT表中进行选择,将数据插入GTT。在此步骤中插入的行数从6000行到300万行不等。
2.使用仅涉及GTT的Update语句更新插入的数据这次更新也使用了一些聚合函数。
我尝试过,但无法在测试环境中复制此内容。我认为一个不错的选择是在步骤1之后修改流程以收集特定于会话的统计信息。但是,我们无权编辑代码。
谢谢你的帮助。
专家解答
如果数据是通过直接加载加载的,那么加载时的统计信息的标准集合就像普通表一样执行,例如
而常规的行负载不会
这可以解释为什么即使没有明确的dbms_stats调用,您也会获得统计数据。
不幸的是,如果要执行更频繁的统计信息收集,则需要使用自己的dbms_stats调用拦截代码。另一种选择是禁用会话统计信息,并完全依赖动态采样。
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进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




