特定分区的Oracle gather_database_stats

hgqdbh6s  于 2023-11-17  发布在  Oracle
关注(0)|答案(1)|浏览(131)
select * from v$version
BANNER                                                                          
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
CORE    11.2.0.4.0  Production  
TNS for IBM/AIX RISC System/6000: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 - Production

字符串
我希望使用DBMS_STATS.GATHER_DATABASE_STATS使用obj_filter_list参数来收集特定表和分区的统计信息。我意识到Oracle可以自动收集统计信息,这通常是最好/最有效的方法,但比我聪明的人已经发现,我们还需要添加这种功能,以使我们能够专注于/在需要的时候指定统计数据收集。我遇到的问题是,如果我“只是”收集表上的统计数据,(使用gather_database_stats),没有问题,dbms_stats.gather_database_stats按预期完成其工作。然而,当我向obj_filter_list添加分区名称时,我只能假设我有点笨,或者我误解了这个过程,或者我做错了什么。
我正在使用的代码(实际上,过滤器列表的填充实际上是通过查询一个包含相关细节的表来完成的)试图收集统计数据。

declare
    filter_list dbms_stats.objecttab := dbms_stats.objecttab();
begin
    filter_list.extend(2);
    filter_list(1).ownname := 'USER01';
    filter_list(1).objname := 'TABLEABC';
    filter_list(1).objtype := 'TABLE';
    filter_list(1).partname := 'PART_CURR';
    
    filter_list(2).ownname := 'USER02';
    filter_list(2).objname := 'TAB_MYTAB';
    filter_list(2).objtype := 'TABLE';
    filter_list(2).partname := 'PART2023'    ;
    
    dbms_stats.gather_database_stats(obj_filter_list => filter_list);
end;
/


任何见解非常赞赏。

icomxhvb

icomxhvb1#

您的代码在我看来是正确的,但我无法让它在19c上工作。不要调用DBMS_STATS.GATHER_DATABASE_STATS并使用参数OBJ_FILTER_LIST,而是调用DBMS_STATS.GATHER_TABLE_STATS并使用参数PARTNAME:

begin
    dbms_stats.gather_table_stats(ownname => user, tabname => 'TABLEABC', partname => 'PART_CURR');
end;
/

字符串
下面是一个基于您的代码的完全可复制的示例。它显示,尽管参数值看似正确,但LAST_ANALYZED字段都设置为NULL,这意味着没有收集统计信息。

-- drop table TABLEABC;
-- drop table TAB_MYTAB;

create table TABLEABC(a number, b number)
partition by list(a)
(
    partition p1 values (1),
    partition PART_CURR values(3)
);

create table TAB_MYTAB(a number, b number)
partition by list(a)
(
    partition p1 values (1),
    partition PART2023 values(3)
);

declare
    filter_list dbms_stats.objecttab := dbms_stats.objecttab();
    output_object_list dbms_stats.objecttab;
begin
    filter_list.extend(2);
    filter_list(1).ownname := user;
    filter_list(1).objname := 'TABLEABC';
    filter_list(1).objtype := 'TABLE';
    filter_list(1).partname := 'PART_CURR';

    filter_list(2).ownname := user;
    filter_list(2).objname := 'TAB_MYTAB';
    filter_list(2).objtype := 'TABLE';
    filter_list(2).partname := 'PART2023'    ;

    dbms_stats.gather_database_stats(obj_filter_list => filter_list, objlist => output_object_list);
end;
/

select last_analyzed from dba_tables where table_name in ('TABLEABC', 'TAB_MYTAB');
select last_analyzed, dba_tab_partitions.* from dba_tab_partitions where table_name in ('TABLEABC', 'TAB_MYTAB');


但是使用PARTNAME参数调用DBMS_STATS.GATHER_TABLE_STATS将正确设置LAST_ANALYZED值。
其中一个few sources提到了这个过滤器参数,这意味着过滤器列表只有在你还使用输出对象列表时才能工作。然而,即使我设置了这个输出参数,功能仍然不起作用。我甚至在Oracle支持上找不到引用的错误编号。
这个特性看起来很少见,而且有很多bug。即使你找到了一些方法来使OBJ_FILTER_LIST工作,你也应该避免它。

相关问题