数据库中如何实现全局临时表GTT的统计信息

86次阅读
没有评论

共计 2612 个字符,预计需要花费 7 分钟才能阅读完成。

这篇文章主要介绍数据库中如何实现全局临时表 GTT 的统计信息,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

我们都知道,全局临时表 GTT 分为两种,一种是 transaction level,一种是 session level,

分别通过 on commit delete rows/preserve rows 实现,其中 session level 表示在本 sessoin
数据有效,相同 session 内,之前事务操作的数据,对于后续的操作都可见,而事务级的 GTT 表示
一旦事务结束 (commit) 那么立即 delete,相同 session 的后续操作看不到之前事务操作。
在 9i 阶段可以使用 GATHER_TABLE_STATS 调用来收集统计信息须传入参数 GATHER_TEMP 为 TRUE,
10g 开始 oracle 对于普通表和 GTT 收集统计信息并没有特殊处理,都是通过 GATHER_TABLE_STATS
存储过程来收集,但是由于上述的两种 GTT 特殊性,收集统计信息有特殊性:

1. 对于 session level 的,因为 GTT 数据并不持久化,存在 session 隔离性,需要在当前 session 收集,
若是通过另起窗口 (新 session) 收集统计信息会不成功, 原因就是收集统计信息的 session 没有数据,
自然也收集不到统计信息了。

2. 对于 transaction level 的,即便是当前 session 收集,因为 GATHER_TABLE_STATS 会先执行默认提交,
所以数据就自动删除,自然也就没有数据可收集了。所以针对这种情景,oracle 有官方 note 403587.1 介绍
下面就是移花接木办法来收集事务级 GTT 的步骤
1. create a PRESERVE ROWS table
SQL create global temporary table TT(I number) on commit preserve rows;
2. populate with representative data
SQL insert into TT select rownum from dba_objects where rownum 1000;
3. gather stats
SQL exec dbms_stats.gather_table_stats(null, TT
4. create a STAT table
SQL exec dbms_stats.create_stat_table(null, TTSTATS
5. export the stats from the PRESERVE ROWS table
SQL exec dbms_stats.export_table_stats(null, TT ,null, TTSTATS ,null,true);
6. truncate then drop the PRESERVE ROWS table
SQL truncate table TT;
SQL drop table TT;
7. now create the real temporary table (defined using DELETE ROWS – the default)
SQL create global temporary table TT(I number);
8. finally import the stats exported from the STAT table
SQL exec dbms_stats.import_table_stats(null, TT ,null, TTSTATS ,null,true);

3. 在 12c 版本,oracle 已经进步改善了对这种 transaction level GTT 的统计信息收集,
也就是说 GATHER_TABLE_STATS 收集统计信息的时候不会默认发起 commit,这样就不会
破坏当前 session 的事务完整性,收集统计信息的存储过程就可以看到当前 session 的
数据情况并收集统计信息。
下面是一个简单的测试过程:
3.1. 创建 transaction level GTT
Create Global Temporary Table maob_temp  (a number,b varchar2(100)) On Commit delete Rows; delete Rows
Table created.

3.2. 插入数据
insert into maob_temp select rownum,object_name from dba_objects where rownum 1000;
SQL

999 rows created.

3.3. 收集统计信息
exec dbms_stats.gather_table_stats(user, MAOB_TEMP
SQL
PL/SQL procedure successfully completed.

3.4.check 是否数据已经被删除
 select count(*)from maob_temp;
SQL
  COUNT(*)
———-
  999

3.5. 查看统计信息是否已经收集成功  
SQL select TABLE_NAME,NUM_ROWS,BLOCKS,SCOPE from DBA_TAB_STATISTICS where owner= MAOB AND TABLE_NAME= MAOB_TEMP

TABLE_NAME  NUM_ROWS BLOCKS SCOPE
————————————–
MAOB_TEMP  0  0 SHARED
MAOB_TEMP 999  4 SESSION

注意:这一步要在和上述步骤相同的 session 执行,因为 12c 的这个新功能默认对 GTT 收集统计信息是 session scope 的,也就是说统计信息也是
session 隔离的,其他 session 看不到这个 session 收集的统计信息,若是变成传统的 shared scope,那么仍然会默认先 commit 再收集
统计信息并记录数据字典表,供其他 session 使用,对于 transaction level 仍然存在先 commit 在收集情况,那么要解决问题,仍需要参考步骤
2 的移花接木办法, 但是创建表之后要先指定为 shared scope 再收集统计信息。
EXEC DBMS_STATS.SET_TABLE_PREFS (NULL, TT , GLOBAL_TEMP_TABLE_STATS , SHARED

以上是“数据库中如何实现全局临时表 GTT 的统计信息”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注丸趣 TV 行业资讯频道!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-07-20发表,共计2612字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)