最新数据库部分大表非常慢,发现是没有做统计信息收集,执行了统计信息收集,如下:发现查询速度明显提高。
EXEC dbms_stats.gather_table_stats(ownname => 'user',tabname => 'class',estimate_percent => null,partname => 'class388',method_opt => 'for all indexed columns',degree => '8');但是怎么对这些大表写一个sh,  然后crontab执行一个定时任务进行更新了。因为这写大表是分片表,我这边的难点就是:
1)分片的信息和表的名称怎么把SQL 传递到SHELL里?
2) shell里 dbms_stats.gather_table_stats 命令是否可以带变量直接执行?
#!/bin/sh
. /export/home/npmuser/.profile
cd /export/home/npmuser/yn_kpi_sum
orauser=`awk '{print $1}' ora_login.conf`
orapwd=`awk '{print $2}' ora_login.conf`
orasid=`awk '{print $3}' ora_login.conf`
sqlplus -S $orauser/$orapwd@$orasid <<EOF
set heading off feedback off pagesize 0 verify off echo off

解决方案 »

  1.   


    -- 使用这个,对该用户下的所有表都收集一下,包含了所有的表;
    exec dbms_stats.gather_schema_stats(ownname => user,cascade => true) ;
      

  2.   

    建 一个存储过程吧,把要收集的表,都加进来,写一个循环, shell 直接调用这个过程;以后,改起来也方便;
      

  3.   

    存储过程如下:
    create or replace procedure auto_gathertable is
    begin
      for p in (
      select partition_name,
             table_name
             from tac_frag_manager
             where lower(table_name) = 'tcc_eutrancell'
                   and begin_time = trunc(sysdate) - 1)
      loop
        begin
        dbms_stats.gather_table_stats(ownname => 'NPMUSER',tabname => 'p.table_name',estimate_percent => null,partname => 'p.partition_name',method_opt => 'for all indexed columns',degree => '8');
        exception
          when others then
            insert into yy_test_log
            values
              ('partition_name', -1, sysdate, p.table_name);
            commit;
            continue;
        end;
      end loop;
    end auto_gathertable;手工执行:
    exec auto_gathertable;   没有任何反应,怎么调试?
      

  4.   

    ORA-20001: P.TABLE_NAME is an invalid identifier
    ORA-06512: at "SYS.DBMS_STATS", line 20337
    ORA-06512: at "SYS.DBMS_STATS", line 20360
    ORA-06512: at "NPMUSER.AUTO_GATHERTABLE", line 11
    ORA-06512: at line 2
    这个是报错信息
      

  5.   

             where lower(table_name) = 'tcc_eutrancell'
                   and begin_time = trunc(sysdate) - 1)这个能查出数据来吗? 注意你这里的是  = ;