【问题标题】:What does Oracle DB do for the first query of a clustered table?Oracle DB 对聚簇表的第一次查询做了什么?
【发布时间】:2015-05-27 23:44:29
【问题描述】:

我们有一个关于 oracle 集群和聚簇表的问题。

本质上我们创建了一个集群、一个集群表和一个集群索引:

create cluster testcluster1(id number(5)) size 1000 storage(initial 1024m);

create table test_tab1(id number(5), num number(5), str2 varchar2(20),str3 varchar2(20)) cluster testcluster1(id);

create index test1clusterindex on cluster testcluster1;

然后我们将数据插入到表中:

declare

  lower NUMBER := 1;

  upper NUMBER := 10000000;

begin

  FOR i In lower .. upper LOOP

    INSERT INTO test_tab1 VALUES(floor(i / 800000),

                           floor(i / 800000),

                           'xxxxxxxxxxxxxxxxxxx',

                           'xxxxxxxxxxxxxxxxxxx');
  END LOOP;

end;

一次普通​​的全表扫描需要的时间是~6s:

select sum(t.num) from TEST_TAB1 t;

集群扫描的第一次查询所需时间约为 61 秒:

select sum(t.num) from TEST_TAB1 t where t.id <= 4

同一个集群扫描的后续查询非常快(~0.4s),因为集群、集群表和集群索引被加载到默认缓冲区缓存中(我们知道这一点是因为刷新缓冲区缓存会恢复长集群扫描的时间约为 61 秒)。但是除了在集群扫描的第一个查询中加载集群和集群表(即使是全表扫描也需要大约 6 秒),Oracle DB 应该做其他事情(大约需要 55 秒)。

所以我们的问题是,在这约 55 秒的时间内,oracle DB 在集群扫描的第一个查询中做了什么?任何 cmets 将不胜感激!

【问题讨论】:

  • 您应该从查看解释计划开始,如果这不能证明可以解释此效果的差异,则使用等待事件跟踪——后者将是有关该时间在哪里的权威信息走了。
  • 非常感谢 cmets!我们今天使用等待事件跟踪进行了测试,发现全表扫描和远程集群扫描的缓冲区缓存不同。全表扫描使用 db_file_scatter 读取(将多块读取到许多不连续的 SGA 缓冲区),而集群扫描使用 db_file_sequential 读取(将单个块顺序读取到连续的 SGA 缓冲区)。这可以很好地解释全表扫描和集群扫描第一次查询的时间差。

标签: sql oracle


【解决方案1】:

第一个查询执行完整扫描并按顺序读取块。第二个查询对集群索引执行范围扫描并访问每个 id 的表。这导致更多的逻辑读取以及随机读取。结果是一个较慢的查询。从解释计划开始,您将看到访问路径;然后你可以在统计或自动跟踪的情况下运行,看看会发生什么!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 2012-10-10
    • 2013-07-09
    • 1970-01-01
    相关资源
    最近更新 更多