ITPub博客

首页 > 数据库 > 数据库开发技术 > 临时表在收集统计的时候会出现的问题

临时表在收集统计的时候会出现的问题

原创 数据库开发技术 作者:litterbaby 时间:2007-04-09 12:27:22 0 删除 编辑
临时表在收集统计的时候会出现的问题[@more@]

临时表在收集统计的时候会出现的问题

添加一个临时表:

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

表已创建。

SQL> insert into gtt select rownum from all_objects where rownum <= 1000;

已创建1000行。

SQL> set autotrace on exp

SQL> select count(*) from gtt;

COUNT(*)

----------

1000

执行计划

----------------------------------------------------------

Plan hash value: 3344941513

-------------------------------------------------------------------

| Id | Operation | Name | Rows | Cost (%CPU)| Time |

-------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 2 (0)| 00:00:01 |

| 1 | SORT AGGREGATE | | 1 | | |

| 2 | TABLE ACCESS FULL| GTT | 1000 | 2 (0)| 00:00:01 |

-------------------------------------------------------------------

Note

-----

- dynamic sampling used for this statement

SQL>

另外启动一个Session。

SQL> conn test/test

已连接。

SQL> select * from gtt;

未选定行

SQL> set autotrace on exp

SQL> select * from gtt;

未选定行

执行计划

----------------------------------------------------------

Plan hash value: 917624683

--------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

--------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 13 | 2 (0)| 00:00:01 |

| 1 | TABLE ACCESS FULL| GTT | 1 | 13 | 2 (0)| 00:00:01 |

--------------------------------------------------------------------------

Note

-----

- dynamic sampling used for this statement

SQL>

这是正确的,但是如果我们使用dbms_stats.gather_table_stats这个收集一下临时表的统计信息时候,就会出现问题了。

#Session 1

SQL> exec dbms_stats.gather_table_stats(user,'GTT');

PL/SQL 过程已成功完成。

SQL> select count(*) from gtt;

COUNT(*)

----------

1000

执行计划

----------------------------------------------------------

Plan hash value: 3344941513

-------------------------------------------------------------------

| Id | Operation | Name | Rows | Cost (%CPU)| Time |

-------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1 | 2 (0)| 00:00:01 |

| 1 | SORT AGGREGATE | | 1 | | |

| 2 | TABLE ACCESS FULL| GTT | 1000 | 2 (0)| 00:00:01 |

-------------------------------------------------------------------

这时可以看到这里使用的不是动态收集的选项,而是我们收集的统计信息,在这个会话中是正确的。

#Session 2

SQL> select * from gtt;

未选定行

执行计划

----------------------------------------------------------

Plan hash value: 917624683

--------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

--------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 1000 | 3000 | 2 (0)| 00:00:01 |

| 1 | TABLE ACCESS FULL| GTT | 1000 | 3000 | 2 (0)| 00:00:01 |

--------------------------------------------------------------------------

这就出现问题,明明在这个会话中没有数据的,而执行计划上却显示有1000行的数据,这就造成了问题。

这个问题产生的原因是因为:临时表有两种类型的,一是会话级的,二是事务级的,而我们收集统计信息,但是由于临时表的特殊性,只是在一个会话上当时的情况下收集的,只能反应当时一个瞬间的数据的状态,由于临时表上的数据在会话之间,事务之间是变化的,这样就会产生这样的问题。

解决办法:

解决的方法有两种:

1、 在9i2之前由于没有动态采集信息的方案,建议根据临时表的典型特征来使用dbms_stats.set_table_stats来固定统计数据。

在9i2之后,可以使用动态采集,不需要人工对临时表进行统计数据的采集。

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/222350/viewspace-909443/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
  • 博文量
    131
  • 访问量
    465725