Oracle FAQ Your Portal to the Oracle Knowledge Grid
HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US
 

Home -> Community -> Mailing Lists -> Oracle-L -> Re: UPDATE STATISTICS

Re: UPDATE STATISTICS

From: <bmarialuz_at_netscape.net>
Date: Thu, 25 Jan 2001 16:50:12 -0500
Message-Id: <10752.127546@fatcity.com>


Is this what you are looking for?

rem $DBA/analyze.sql
rem
rem Performs an ANALYZE COMPUTE STATISTICS on all non-SYS/SYSTEM-owned tables rem and indexes.
rem
rem Creates an analysis report (analyze.lis) of all analyzed tables and indexes. rem
rem ***** Notes: *****

rem    1) This may take many hours when analyzing large tables!
rem    2) The analyze will AUTOMATICALLY turn on Cost-Based Optimization !!!
rem    3) Oracle requires locks on the tables to be analyzed.  If this prevents
rem       this script from successfully executing, use the analinds.sql script.
rem
rem Last Change 05/22/97 by Brian Lomasky rem
set echo off
set feedback off
set heading off
set pagesize 0
set serveroutput on size 1000000
set termout off
set verify off
drop table anal_temp;
set termout on
create table anal_temp (lineno number, text varchar2(80)); declare

    cursor time_cursor is select

        to_char(sysdate, 'HH:MI:SS')
        from dual;

    cursor tab_cursor is select
        owner,
        table_name,
        num_rows,
        chain_cnt,
        avg_row_len
        from sys.dba_tables
        where owner != 'SYS' and owner != 'SYSTEM'
        and table_name != 'ANAL_TEMP'
        order by owner, table_name;

    cursor ind_cursor (c_own VARCHAR2, c_tab VARCHAR2) is select
        to_char(sysdate, 'HH:MI:SS'),
        index_name,
        decode(uniqueness,

'NONUNIQUE','Non-Unique',
'UNIQUE',' Unique',
'BITMAP',' Bitmap', uniqueness),
distinct_keys from sys.dba_indexes where owner = c_own and table_name = c_tab order by index_name; cursor col_cursor (c_own varchar2, c_ind varchar2) is select decode(column_position, 1, column_name, ', ' || column_name) from sys.dba_ind_columns where index_owner = c_own and index_name = c_ind order by column_position; lv_owner sys.dba_tables.owner%TYPE; lv_table_name sys.dba_tables.table_name%TYPE; lv_num_rows sys.dba_tables.num_rows%TYPE; lv_chain_cnt sys.dba_tables.chain_cnt%TYPE; lv_avg_row_len sys.dba_tables.avg_row_len%TYPE; lv_index_name sys.dba_indexes.index_name%TYPE; lv_distinct_keys sys.dba_indexes.distinct_keys%TYPE; lv_column_name sys.dba_ind_columns.column_name%TYPE; lv_uniqueness char(10); now varchar2(8); lineno number; recno number; n number; a_lin varchar2(80); x varchar2(80); function vwri(x_lin in varchar2, x_str in varchar2, x_force in number) return varchar2 is begin if length(x_lin) + length(x_str) > 80 then lineno := lineno + 1; insert into anal_temp values (lineno, x_lin); if x_force = 0 then return ' ' || x_str; else lineno := lineno + 1; insert into anal_temp values (lineno, x_str); return ''; end if; else if x_force = 0 then return x_lin||x_str; else lineno := lineno + 1; insert into anal_temp values ( lineno, x_lin||x_str); return ''; end if; end if;

    end vwri;

    function format_owner_table (the_owner in varchar2,

        the_table in varchar2) return varchar2 is     begin

        n := length(the_owner) + length(the_table);
        if n < 40 then
            return rpad(the_owner || '.' || the_table, 40);
        else
            return '..' || substr(the_owner || '.' || the_table,
                n-36, 38);
        end if;

    end format_owner_table;

    procedure wri (my_txt in varchar2) is     begin

        lineno := lineno + 1;
        insert into anal_temp values (lineno, my_txt);
    end wri;

begin

    lineno := 0;
    recno := 0;
    /* Analyze all of the desired tables and indexes */     open tab_cursor;
    loop

        open time_cursor;
        fetch time_cursor into now;
        close time_cursor;
        fetch tab_cursor into
            lv_owner,
            lv_table_name,
            lv_num_rows,
            lv_chain_cnt,
            lv_avg_row_len;
        exit when tab_cursor%notfound;

        dbms_output.put_line('Starting analysis of ' ||
            format_owner_table(lv_owner, lv_table_name) ||

' at ' || now);
/* Analyze each table */ dbms_ddl.analyze_object('TABLE', lv_owner, lv_table_name,
'COMPUTE');
open ind_cursor(lv_owner, lv_table_name); loop fetch ind_cursor into now, lv_index_name, lv_uniqueness, lv_distinct_keys; exit when ind_cursor%notfound; dbms_output.put_line('Starting analysis of ' || rpad(lv_index_name, 40) || ' at ' || now); /* Analyze each index for this table */ dbms_ddl.analyze_object('INDEX', lv_owner, lv_index_name, 'COMPUTE'); end loop; close ind_cursor;

    end loop;
    close tab_cursor;

    dbms_output.put_line('Done with analysis at ' || now);

    /* Rerun all the cursors again to create the report */

    wri('                                                            ' ||
        '   Avg');
    wri('                                                       Chain' ||
        '   Row   Distinct');
    wri('Object Owner / Name                       Num Rows     Count' ||
        '   Len     Keys');
    wri('---------------------------------------- --------- ---------' ||
        ' -----  ---------');

    open tab_cursor;
    loop

        fetch tab_cursor into
            lv_owner,
            lv_table_name,
            lv_num_rows,
            lv_chain_cnt,
            lv_avg_row_len;
        exit when tab_cursor%notfound;

        recno := recno + 1;
        if recno > 1 then
            wri(' ');
        end if;

        wri(format_owner_table(lv_owner, lv_table_name) ||
            to_char(lv_num_rows, '999999999') ||
            to_char(lv_chain_cnt, '999999999') ||
            to_char(lv_avg_row_len, '99999'));

        open ind_cursor(lv_owner, lv_table_name);
        loop
            fetch ind_cursor into
                now,
                lv_index_name,
                lv_uniqueness,
                lv_distinct_keys;
            exit when ind_cursor%notfound;

            wri(rpad('  ' || lv_uniqueness || ' ' || lv_index_name,
                40) || '                           ' ||
                to_char(lv_distinct_keys, '999999999'));

            a_lin := '             Indexed columns: ';
            open col_cursor(lv_owner, lv_index_name);
            loop
                fetch col_cursor into lv_column_name;
                exit when col_cursor%notfound;
                a_lin := vwri(a_lin, lv_column_name, 0);
            end loop;
            close col_cursor;
            a_lin := vwri(a_lin, '', 1);

            /* Analyze for proper index type */
            if lv_uniqueness = 'Non-Unique' then
                if lv_distinct_keys < 21 then
                    wri('');
                    wri('  *************************' ||
                        '**************************' ||
                        '***************************');
                    wri('  ** The above non-unique index' ||
                        ' might not be appropriate,' ||
                        ' since non-unique    **');
                    wri('  ** indexes should be created' ||
                        ' on columns which return' ||
                        ' no more than 2-4% of   **');
                    wri('  ** the total number of rows' ||
                        ' in the table - Assuming' ||
                        ' an average distribution **');
                    x := to_char(trunc(100 /
                        lv_distinct_keys));
                    wri('  ** of values, this index will' ||
                        ' return ' || x ||
                        '% of the rows' || substr(
                        '                         ',
                        1, 26 - length(x)) || '**');
                    wri('  *************************' ||
                        '**************************' ||
                        '***************************');
                    wri('');
                end if;
            elsif lv_uniqueness = '    Bitmap' then
                if lv_distinct_keys / lv_num_rows > .001 then
                    wri('');
                    wri('  *************************' ||
                        '**************************' ||
                        '***************************');
                    wri('  ** The above bitmap index' ||
                        ' might not be appropriate,' ||
                        ' since bitmap indexes    **');
                    wri('  ** should be created on' ||
                        ' columns having no more' ||
                        ' than 1 unique value' ||
                        ' per      **');
                    x := to_char(trunc(lv_num_rows /
                        lv_distinct_keys));
                    wri('  ** 1000 rows - This index' ||
                        ' currently has 1 unique' ||
                        ' value per ' || x || ' rows' ||
                        substr('           ',
                        1, 12 - length(x)) || '**');
                    wri('  *************************' ||
                        '**************************' ||
                        '***************************');
                    wri('');
                end if;
            end if;

        end loop;
        close ind_cursor;

    end loop;
    close tab_cursor;

    commit;
exception

        when others then
                rollback;
                raise_application_error(-20000,
                        'Unexpected error on ' || lv_owner || '.' ||
            lv_table_name || ': ' || to_char(SQLCODE) || chr(10) ||
            sqlerrm || chr(10) || 'Aborting...');
end;
/

set termout off
spool analyze.lis
select text from anal_temp order by lineno; spool off
drop table anal_temp;
set termout on
select 'Created analyze.lis report for your viewing pleasure...' from dual; exit


ORACLE-L_at_fatcity.com wrote:

> Anyone have a good script to analyse stats for COST based optimizer
> for the whole database..
> 
> Is there a procedure to do this in one of the packages?
> 
> thanks,
> Bruce
> 
> -- 
> Please see the official ORACLE-L FAQ: http://www.orafaq.com
> -- 
> Author: 
>   INET: bruce.taneja_at_mcd.com
> 
> Fat City Network Services    -- (858) 538-5051  FAX: (858) 538-5051
> San Diego, California        -- Public Internet access / Mailing Lists
> --------------------------------------------------------------------
> To REMOVE yourself from this mailing list, send an E-Mail message
> to: ListGuru_at_fatcity.com (note EXACT spelling of 'ListGuru') and in
> the message BODY, include a line containing: UNSUB ORACLE-L
Received on Thu Jan 25 2001 - 15:50:12 CST

Original text of this message

HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US