21

有没有办法更新所有表的所有统计信息而不考虑所有者?

我找到了这个片段,但我不确定这是否会抓住所有的桌子......

BEGIN
   FOR A IN ( SELECT owner FROM SYS.all_tables ) LOOP
      execute immediate
        EXEC dbms_stats.gather_schema_stats( 'A.owner', cascade='TRUE');
   END LOOP;
END;
4

3 回答 3

22

使用DBMS_STATS.GATHER_DATABASE_STATS

begin
    dbms_stats.gather_database_stats;
end;
/
于 2013-05-06T07:03:19.973 回答
11

不,DBMS_STATS包一次最多只能执行一个模式。

您可以使用下面的脚本来收集所有模式中所有对象类型的统计信息。您列出的问题有几个问题(无需立即执行,“A.owner”是一个字符串,但它应该是一个对象等)。

您可以添加其他模式以在IN列表中跳过,因为您可能不想为内置模式执行此操作(无论如何它们大多是静态的,所以会浪费)。此外,对于要收集统计信息的每个模式(或以 DBA 身份登录),您都需要拥有适当的权限。

收集所有对象的统计信息(可能是您真正想要的):

BEGIN
    FOR rec IN (SELECT * 
                FROM all_users
                WHERE username NOT IN ('SYS','SYSDBA'))
    LOOP
        dbms_stats.gather_schema_stats(rec.username);
    END LOOP;
END;

仅在表上收集统计信息:

BEGIN
    FOR rec IN (SELECT * 
                FROM all_tables
                WHERE owner NOT IN ('SYS','SYSDBA'))
    LOOP
        dbms_stats.gather_table_stats(rec.owner, rec.table_name);
    END LOOP;
END;
于 2013-05-05T02:24:59.393 回答
0

我对@sehrope 程序进行了修改,以跳过锁定的统计信息和 IOT 表,因为它们将通过异常处理。

BEGIN
    FOR rec IN (SELECT a.owner, a.table_name 
                FROM all_tables a, dba_tab_statistics  s
                WHERE a.owner NOT IN ('SYS','SYSDBA')
                AND 
                (a.iot_type IS NULL
                OR
                a.iot_type != 'IOT_OVERFLOW')
                and a.owner = s.owner and a.table_name = s.table_name and s.STATTYPE_LOCKED is null)
    LOOP
        dbms_stats.gather_table_stats(rec.owner, rec.table_name);
    END LOOP;
END;
于 2021-04-08T20:37:30.587 回答