临时表(GLOBAL TEMPORARY TABLE)及统计信息收集,动态采样

本文探讨了在使用临时表与其他永久表联合查询时,如何通过DBMS_STATS提前收集统计信息来提高执行计划的准确性。重点介绍了GATHER_SCHEMA_STATS/GATHER_TABLE_STATS的使用方法,并解释了动态采样的概念及其在Oracle数据库中的应用,包括初始化参数optimizer_dynamic_sampling的配置和动态采样统计信息的存储机制。
       

我们对临时表进行查询时,分析执行计划会发现临时表估计的返回值很多情况下都是1,这显然
是不对的(因为可能在查询过程中临时表的数据达到几千甚至几万笔),但临时表的数据很快
消失,那么如何在临时表与其他永久表联合查询时能正确得到较好的执行计划呢 ? 

在临时表上也是会执行动态采样的,但是动态采样在SQL解析时完成,所以存在相当大的代价。
所以一般可以使用DBMS_STATS提前收集统计信息。
1. 可以使用GATHER_SCHEMA_STATS或GATHER_TABLE_STATS调用来使用DBMS_STATS。传入
   参数GATHER_TEMP为TRUE(默认为FALSE)。但是要保证在收集统计信息的会话中用代表
   性数据填充全局临时表。
   此外,这个方法只对ON COMMIT PRESERVE ROWS全局临时表收集和存储统计信息。对
   于ON COMMIT DELETE ROWS全局临时表收集不到正确的统计信息。因为调用DBMS_STATS
   将导致提交,而这会擦除ON COMMIT DELETE ROWS表中的所有信息。
2. 如果我们不能保证在收集统计信息的会话中用代表性数据填充全局临时表,也可以
   手动填充临时表的统计信息(注意是代表性数据):
语法:
exec dbms_stats.set_table_stats(ownname,tabname,numrows,numblks,avgrlen);
begin 
 dbms_stats.set_table_stats( 
   wnname => 'APPSYS', 
   tabname => 'DIM_DEL', 
   numrows => 300, 
   numblks => 4, 
   avgrlen => 20); 
end;
或者
BEGIN dbms_stats.set_table_stats(ownname => 'SOAINFRA',tabname => 'DM_MID',numrows =>10000 );END;
最后使用
exec dbms_stats.lock_table_stats(ownname => 'XXXXX',tabname =>'XXXX');
这时会针对这个表对统计信息锁定,之后的analyze及dbms_stats分析对此表操作会报错
ORA-38029: object statistics are locked。
 
 
-- 最后简单说说动态采样 。
动态采样在Oracle9i R2中被引入。
详细可参考博客: http://space.itpub.net/35489/viewspace-592375,这里初略说一下。
初始化参数optimizer_dynamic_sampling的值(或层级)指定动态采样的方式和时间。
动态采样等级以及含义,注意这个参数的默认值由另一个初始化参数optimizer_features_ enable决定。
如果optimizer_features_enable设置为10.0.0或更高,默认值为层级2。大部分时候level2足够了。
如果optimizer_features_enable设置为9.2.0,默认值为层级1。
如果optimizer_features_enable设置为9.0.1或更低,动态采样特性则被禁用。

关闭动态采样的方式: 设置optimizer_dynamic_sampling=0;
 
动态采样的统计信息存在哪里 ?
动态采样得到的统计信息既不存储在数据字典中也不存储在其他地方,真正重用它们的唯
一方式是重用共享游标本身。
 

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

转载于:http://blog.itpub.net/35489/viewspace-748730/

<think>好的,我需要回答用户关于全局临时表在SQL脚本中的行为,特别是在GP(Greenplum)数据库中的情况。首先,我得回忆一下全局临时表的基本概念。全局临时表在SQL中通常用于存储临时数据,但不同数据库的实现可能有所不同。用户提到的是GP数据库,也就是Greenplum,所以需要确认Greenplum对全局临时表的支持情况。 接下来,我需要考虑全局临时表的作用范围。一般来说,全局临时表在会话或事务级别存在,但具体行为可能因数据库而异。例如,在Oracle中,全局临时表的数据是会话私有的,而表结构是全局存在的。但在PostgreSQL中,临时表默认是会话级别的,而Greenplum基于PostgreSQL,所以可能类似。 不过,用户特别询问的是在SQL脚本中的行为。这里需要明确,当在脚本中创建全局临时表时,该表是否在脚本执行期间对所有会话可见,还是仅限于当前会话。此外,临时表的数据是否在事务结束后保留,或者随着会话结束自动删除。 根据Greenplum的文档,临时表在会话结束时自动删除,除非使用ON COMMIT子句指定。全局临时表可能指的是表结构在数据库中存在,但数据是会话或事务私有的。需要验证这一点是否正确,或者是否存在不同的定义。 可能还需要引用相关的文档或资料。例如,用户提供的引用中有一个关于Oracle的全局临时表,但Greenplum可能有不同的实现。因此,应该查找Greenplum的官方文档或可靠资源来确认。 另外,用户提到的引用[3]中提到了部署MySQL镜像,这可能与问题无关,但需要确保回答时专注于GP数据库。 总结来说,回答需要包括以下几点: 1. 全局临时表在GP中的定义和作用范围。 2. 创建语法和选项(如ON COMMIT DELETE ROWS或PRESERVE ROWS)。 3. 在SQL脚本中使用时的行为,如会话隔离性、数据可见性和生命周期。 4. 与普通表的区别及使用场景。 需要确保使用正确的LaTeX格式,如变量和语法使用$...$,独立公式用$$...$$,并生成相关问题。同时,引用来源可能需要调整,用户提供的引用中有部分关于其他数据库的内容,可能需要忽略或说明差异。</think>### 全局临时表在SQL脚本中的行为(Greenplum数据库) 在Greenplum(GP)数据库中,全局临时表Global Temporary Table)的作用范围和行为与普通表有显著差异,主要体现在**数据可见性**和**生命周期管理**上。 #### 1. 定义与作用范围 - **表结构全局可见**:全局临时表的表结构定义存储在系统目录中,对所有会话可见[^2]。 - **数据会话隔离**:每个会话插入的数据仅对当前会话可见,其他会话无法访问。例如: ```sql CREATE GLOBAL TEMPORARY TABLE temp_sales (id INT, amount NUMERIC) ON COMMIT PRESERVE ROWS; ``` 此时`temp_sales`的表结构全局存在,但不同会话插入的数据相互隔离。 #### 2. 生命周期控制 通过`ON COMMIT`子句指定数据保留策略: - **事务级临时表**:`ON COMMIT DELETE ROWS` 事务提交后自动清空数据,例如: $$ \text{事务结束} \Rightarrow \text{数据删除} $$ - **会话级临时表**:`ON COMMIT PRESERVE ROWS` 数据保留至会话结束,例如: $$ \text{会话终止} \Rightarrow \text{数据删除} $$ #### 3. SQL脚本中的行为 - **脚本执行与会话绑定**:在单个脚本执行中,若未显式关闭会话,临时表数据会持续存在直至脚本执行结束(会话级)或事务提交(事务级)[^3]。 - **并发执行隔离**:多个脚本同时运行时,各自维护独立的数据副本,避免冲突。 #### 4. 与普通表的对比 | 特性 | 全局临时表 | 普通表 | |--------------|--------------------------|----------------| | 数据可见性 | 会话私有 | 全局共享 | | 存储位置 | 可能存储在临时表空间 | 常规表空间 | | 清理方式 | 自动按策略清理 | 手动删除 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值