有没有办法更新所有表的所有统计信息而不考虑所有者?
我找到了这个片段,但我不确定这是否会抓住所有的桌子......
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;
有没有办法更新所有表的所有统计信息而不考虑所有者?
我找到了这个片段,但我不确定这是否会抓住所有的桌子......
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;
使用DBMS_STATS.GATHER_DATABASE_STATS:
begin
dbms_stats.gather_database_stats;
end;
/
不,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;
我对@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;