我正在开发Oracle 11g上的DWH.我们有一些大表(2.5亿行),按值划分.每个分区都分配给不同的馈送源,每个分区独立于其他分区,因此可以同时加载和处理它们.
数据分布非常不均匀,我们有数百万行的分区,并且分区不超过一百行,但我没有选择分区方案,顺便说一下我无法改变它.
考虑到数据量,我们必须确保每个分区始终具有最新的统计信息,因为如果后续的详细说明没有对数据的最佳访问权限,它们将永远持续下去.
所以对于每个并发的ETL线程,我们
SELECT /*+ APPEND */ INTO big_table PARTITION(part1) FROM temp_table WHERE partition_colum = PART1
(这种方式我们有直接路径,我们不锁定整个表)
在项目的第一阶段,我们使用了这个APPROX_GLOBAL_AND_PARTITION
策略并且像魅力一样工作
dbms_stats.gather_table_stats(ownname=>myschema,
tabname=>big_table,
partname=>part1,
estimate_percent=>1,
granularity=>'APPROX_GLOBAL_AND_PARTITION',
CASCADE=>dbms_stats.auto_cascade,
degree=>dbms_stats.auto_degree)
Run Code Online (Sandbox Code Playgroud)
但是,我们有一个缺点,当我们加载一个小分区时,APPROX_GLOBAL部分占主导地位(仍然比GLOBAL快很多),对于一个小分区,我们有例如10秒的加载和20分钟的统计.
所以我们建议切换到11g 的INCREMENTAL STATS功能,这意味着你没有指定你修改过的分区,你把所有参数保留在auto中,而Oracle做了它的魔力,自动了解哪个分区有被感动了.它确实有效,我们已经加快了小分区的速度.打开电话后,电话就变成了
dbms_stats.gather_table_stats(ownname=>myschema,
tabname=>big_table,
estimate_percent=>dbms_stats.auto_sample_size,
granularity=>'AUTO',
CASCADE=>dbms_stats.auto_cascade,
degree=>dbms_stats.auto_degree)
Run Code Online (Sandbox Code Playgroud)
请注意,您不再通过分区,并且未指定样本百分比.
但是,我们有一个缺点,可能比前一个更糟糕,这与我们的高水平并行性有关.
假设我们有两个同时启动的大分区,它们几乎同时也会完成加载阶段.
第一个线程结束插入语句,提交并启动统计信息收集.统计程序通知有2个分区已修改(这是正确的,一个已满,第二个被截断,正在进行事务),正确更新了两个分区的统计信息.
最终第二个分区结束,收集统计信息,它看到所有分区已经更新,并且什么也不做(这是不正确的,因为第二个线程同时提交了数据).
结果是:
PARTITION NAME | LAST ANALYZED | NUM ROWS | BLOCKS | SAMPLE SIZE
-----------------------------------------------------------------------
PART1 | 04-MAR-2015 15:40:42 | 805731 | 20314 | 805731
PART2 | 04-MAR-2015 15:41:48 | 0 …
Run Code Online (Sandbox Code Playgroud) 我在hive中计算统计数据时看到的语法似乎表明标题问题的答案是"不":
ANALYZE TABLE [TABLENAME] PARTITION(parcol1=…, partcol2=….) COMPUTE STATISTICS
Run Code Online (Sandbox Code Playgroud)
但是,我想把它扔出去,因为我很惊讶,总是需要编写一个脚本迭代分区来生成每个分区的语句.我们现在在这张小桌子上有大约一千个分区,它将按数量级增长.
顺便说一下,我没有指定分区就尝试了以下内容:
hive> analyze table metrics compute statistics;
FAILED: SemanticException [Error 10115]: Table is partitioned and partition specification is needed
Run Code Online (Sandbox Code Playgroud) 我的问题是我有一个架构,其中所有表的统计信息都被锁定.
我在互联网上发现我可以使用该DBMS_STATS.UNLOCK_TABLE_STATS (SCHEMA_NAME)
程序解锁.
我需要知道的是Oracle如何确定何时锁定统计信息以及何时不确定这些情况.
何时以及如何为Oracle,版本9及更高版本执行表统计信息收集?您将如何收集大型数据库的统计数据,其中统计数据收集将与"营业时间"发生冲突.