【问题标题】:Include table gather stats in procedure在过程中包含表收集统计信息
【发布时间】:2014-10-07 20:20:20
【问题描述】:

朋友们,我正在使用以下过程来移动表、每个表的索引,现在尝试在过程中包含 dbms_stats.gather_table_stats。 不知何故,无论我做什么收集统计数据都不起作用。

有人可以建议我做错了什么吗?

Procedure 接受两个参数 OldTbs = Old Tablespace 和 NewTbs = New Tablespace。

我遵循的逻辑; 循环

  1. 从表空间中移动一张表

  2. 将每个索引移动到 #1 中的表移动

  3. 收集 #1 中移动的表的表统计信息

直到 #2 它工作,现在尝试在表的所有索引重建完成后包含 dbms_stats。 用户有权移动任何架构。

dmbs_stats.gather_table_stats(owner=>.......)


CREATE OR REPLACE PROCEDURE moveTbl (OldTbs in varchar2, NewTbs in varchar2)
    AUTHID CURRENT USER
IS
  CURSOR curTable IS
    SELECT owner, table_name, tablespace_name
      FROM dba_tables
      WHERE tablespace_name = OldTbs
      ORDER BY TABLE_NAME;

   CURSOR curIndex (lTabOwn IN Varchar2, lTabNan IN Varchar2) IS
      SELECT table_owner, table_name, owner, index_name, tablespace_name
        FROM dba_indexes
        WHERE table_owner = lTabOwn
        AND table_name = lTabNam;

BEGIN
  FOR rec1 IN curTable LOOP
    dbms_output.putline(rec1.owner || '.' || rec1.table_name);

    EXECUTE IMMEDIATE 'alter table ' || rec1.owner || '.' || rec1.table_name ||
                      ' move tablespace ' || NewTbs;

  FOR rec2 IN curIndex LOOP
     .....
     .....
     .....

  END LOOP;  --curIndex for loop

  dmbs_stats.gather_table_stats(ownname=>'''||rec1.owner || ''',tabname=> || rec1.table_name ||''', estimate_percent=>100, cascade=>true);

  END LOOP;  --curTable for loop
END moveTbl;

【问题讨论】:

    标签: oracle procedures


    【解决方案1】:

    只需将所有者和表名作为参数传递。您没有构建动态 SQL 语句,因此没有理由引用任何内容

    dbms_stats.gather_table_stats( ownname => rec1.owner,
                                   tabname => rec1.table_name,
                                   estimate_percentage => 100,
                                   cascade => true );
    

    当然,这并没有考虑到您正在编写的代码的潜在智慧。如果您经常将对象从一个表空间移动到另一个表空间,以至于值得编写存储过程,我强烈怀疑您做错了什么。除非您有微不足道的数据量或非常奇怪的数据模式,否则估计为 100 的百分比似乎也很严重。

    【讨论】:

    • 感谢贾斯汀的工作,很长一段时间我无法让它工作,所以最终决定寻求专家的帮助。是的,我认为因为我引用了复杂的东西。我有一个包含各种程序的包并使用包来移动对象,数据大小> 3TB。我还将估算百分比降低到 10%。
    • @homer - 首先为什么要将 3 TB 数据从一个表空间移动到另一个表空间?这似乎非常可疑。根据您的 Oracle 版本,我建议让 Oracle 选择样本大小dbms_stats.auto_sample_size。但是,对于这么多数据,除非一开始的统计数据很糟糕,否则我只会将它们保存下来并在移动后导入它们,而不是承担收集它们的所有成本。当然,我通常不会首先将表移动到不同的表空间。
    • Oracle 11gR2 版本,太好了.. auto_sample_size 将是最好的选择,将阅读手册。我只是按照要求清理旧表空间。
    • 您还需要设置cascade => false。索引重建会自动收集统计信息,最后无需重新收集。
    猜你喜欢
    • 1970-01-01
    • 2017-05-15
    • 1970-01-01
    • 2018-01-13
    • 1970-01-01
    • 1970-01-01
    • 2021-07-28
    • 2013-06-30
    • 1970-01-01
    相关资源
    最近更新 更多