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

临时表在收集统计的时候会出现的问题[@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博客 ” ,链接:http://blog.itpub.net/222350/viewspace-909443/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/222350/viewspace-909443/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值