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;
/
非常感谢任何见解。
你的代码对我来说看起来是正确的,但我无法让它在 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 值。
提到此过滤器参数的少数来源之一暗示存在一个错误,即过滤器列表仅在您还使用输出对象列表时才起作用。但是,即使我设置了该输出参数,该功能仍然无法工作。我什至在 Oracle 支持上找不到引用的错误号。
该功能似乎很少见且存在缺陷。即使您确实找到了某种方法使 OBJ_FILTER_LIST 起作用,您也应该避免它。