| Oracle FAQ | Your Portal to the Oracle Knowledge Grid | |
Home -> Community -> Mailing Lists -> Oracle-L -> Re: UPDATE STATISTICS
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
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;
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;
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;
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-LReceived on Thu Jan 25 2001 - 15:50:12 CST
![]() |
![]() |