#!/usr/bin/ksh # set -xv # author : B. Polarski # program : smenu_gather_stat_tbl.ksh # date : 01 October 2005 # Apapted to Smenu by B. Polarski # Modified: 04 October HOST=`hostname` HOST=`echo $HOST | awk '{ printf ("%-+15.15s",$1) }'` # ----------------------------------------------------------------------------------------------------------------------- function help { more < sta -u -t [-p ] [-f] [-s ] [-o ] [-n ] -part [partname] -col ... -col -c -cl -cp -x -ka -kc -lock|-unlock sta -u -i [-p ] [-s ] [-o ] [-n ] -part [partname] -cp -cl -x sta -u -l |-m [-s ] [-b ] sta -fx | -dx/-dy OR sta -fy [start |stop] [-int ] sta -e -s -f [-t
] [-i ] [-u ] -c sta -e -u -y sta -a -s [-t
] [-i ] [-u ] -c -n -o sta -del -s [-t
] [-i ] [-u ] -c -fx : gather stat for fixed tables -dx : delete stat for fixed tables -fy : gather system statistics -dy : delete system statistics -p : Percent sample on each objects (default to 5%) -part : Partition name -i : the index -n : statid -v : show execution -x : execute the output of this scripts -y : export or import will also do system statistics -lp : List dbms_stat default parameters -t : the table -d : degree (default to 2x cpu) -col ..... -col gather stats only for columns name list -f : Copy gathered statistics to sm_stattab. It is needed if you intend to export/import statistics -a : import stats from into schema -u or into table -t
or -i -n -c : Set cascade=TRUE to gather statistics also on the indexes for this table. Index statistics gathering is not parallelized. This option is equivalent to running the GATHER_INDEX_STATS procedure on each of the table's indexes. (default is FALSE). This parameter is only for table -ka : For table only; set the number of histogram buckets for all columns: -k 100 -kc : For table only; set the number of histogram buckets per each columns. Give the string list used by method_opt -del : delete stats from and schema -u -n -t
-part [partname] -cp -cl -ci -cp : delete cascade to partitions if partname is NULL -cl : delete cascade to columns -ci : delete cascade to indexes -i -part [partname] -cp -g : granularity, values are : DEFAULT Gather global- and partition-level statistics PARTITION Gather partition-level statistics. SUBPARTITION Gather subpartition-level statistics. GLOBAL Gather global statistics (default) * ALL Gather all (subpartition, partition, and global) statistics -e : export stats to from schema -u , from table -t
or from index -i -l : list existing stat table and statid. With -s , gives details per type for each object -lock|-unlock : if table name is not given then lock/unlock stats at schema level -m : Create stat table given by -s
-b create stattable in TABLESPACE otherwise default is used -o : can be different than the objects analyzed -s : Table that will hold stat of the table. (default is sm_stattab) -u : the table(s) or index(es) owner. If only the owner is given, then gather stats for schema Note : sta -u -l -s give types per object. Use tbl [-u ] -t
-s to see stats on column for a table EOF exit } # ----------------------------------------------------------------------------------------------------------------------- if [ -z "$1" ];then help; exit fi typeset -u ftable typeset -u findex typeset -u fowner typeset -u fgran typeset -u fcasc typeset -u fstattatb typeset -u FVAR typeset -u COL_LIST unset l_part CHECK_STR="#DEFAULT#PARTITION#SUBPARTITION#GLOBAL#ALL#" CREATE_STATTAB=FALSE LIST_STAT=FALSE EXECUTE=FALSE EXPORT_STAT=FALSE IMPORT_STAT=FALSE STAT_SYSTEM=FALSE fdate=`date +%m%d%H%M` fperc=dbms_stats.auto_sample_size fgran='ALL' fcasc=FALSE fcpu=`$SBIN/module2/s1/smenu_list_init_param.sh -p cpu_count` fdegree=`expr $fcpu \* 2` while [ -n "$1" ] do case "$1" in -a ) IMPORT_STAT=TRUE;; -b ) FVAR=$2 TBS=", '$FVAR'" shift ;; -c ) fcasc=TRUE ;; -del ) fdel=TRUE ;; -cl ) DEL_CASC_COL=",cascade_columns => TRUE ";; -cp ) DEL_CASC_PART=",cascade_parts => TRUE ";; -col ) if [ -n "$COL_LIST" ];then COL_LIST="${COL_LIST}, $2" else COL_LIST="$2" fi shift ;; -d ) fdegree=$2 shift ;; -e ) EXPORT_STAT=TRUE; COPY_ST_STTAB=TRUE;; -g ) fgran=$2 if [ -n "${CHECK_STR##*$fgran*}" ];then echo "########################################" echo "Wrong granularity value " echo "########################################" echo "\n Must be in ; \n`echo $CHECK_STR |tr '#' '\n'`" help fi shift;; -h ) help;; -fx ) CHOICE=GFIX ; GET=TRUE;; -fy ) CHOICE=GSYS ; GET=TRUE if [ "$2" = "-x" -o -z "$2" ] ;then : else MODE=$2; shift fi;; -dy ) CHOICE=GSYS ; GET=FALSE ;; -dx ) CHOICE=GFIX ; GET=FALSE;; -i ) findex=$2 ; shift ;; -int ) INT_MINUTES=$2; shift ;; -l ) LIST_STAT=TRUE ;; -lp ) CHOICE=LIST_PARAM ;; -ka ) METHOD_OPT=" ,method_opt=>'for all columns size $2',";shift ;; -kc ) METHOD_OPT=" ,method_opt=>'$2',";shift ;; -n ) l_fstatid=$2 shift ;; -o ) fstat_owner=$2 shift ;; -m ) CREATE_STATTAB=TRUE ;; -p ) fperc=$2 shift ;; -part ) l_part=$2 shift ;; -s ) l_fstattab=$2 shift ;; -t ) ftable=$2 shift ;; -u ) fowner=$2 shift ;; -v ) SETXV="set -x" ;; -x ) EXECUTE=TRUE ;; -y ) STAT_SYSTEM=TRUE ;; -f ) COPY_ST_STTAB=TRUE ;; -lock ) LOCK=TRUE ; unset UN ;; -unlock ) LOCK=TRUE ; UN=UN ;; * ) echo "Invalid argument $1" $help ;; esac shift done # ------------------------------------------------------------------------------------- function ret_part { arg=$1 cpt=$2 TYPE=$3 # value is TAB or IND if [ $cpt -gt 0 -a ! "$fgran" = "PARTITION" ];then case $arg in PART_NAME ) echo SUBPARTITION_NAME ;; DBA_TAB ) echo DBA_${TYPE}_SUBPARTITIONS ;; esac if [ "$fgran" = "ALL" -o "$fgran" = "SUBPARTITION" ];then : else echo "Garther stats for subpartitions are only done for Granularity = \"ALL\" or \"SUBPARTITION\"" echo "If you are not happy with that, you can send your instults at ceo@Oracle.com" echo "Aborting ==>" exit 0 fi else case $arg in PART_NAME ) echo PARTITION_NAME ;; DBA_TAB ) echo DBA_${TYPE}_PARTITIONS ;; esac fi } # ------------------------------------------------------------------------------------- function get_ind_nbr_part { var=`sqlplus -s "$CONNECT_STRING"<" exit fi nbr=`echo $fvar | wc -w` if [ ! $nbr -eq 1 ];then echo "Mutilple user (\"`echo $var | tr '\n' ' '`\") or non existent table ==> abort" echo "user -u " exit else fowner=`echo $fvar | awk '{print $1}'` if [ -z $fowner ];then echo "Owner is blank" exit 1 fi fi fi if [ -z "$l_fstatid" ];then var=`echo $ftable | cut -c1-12` fstatid=$var$fdate else fstatid=$l_fstatid AND_STATID=" and statid='$l_fstatid' " fi fstattab=${l_fstattab:-sm_stattab} fstat_owner=${fstat_owner:-$fowner} fpart=${l_part:-NULL} FOUT=$SBIN/tmp/gather_tbl_stats_${ftable}_${fowner}.log FIL_EXECUTE=$SBIN/tmp/sta_$fstab_$fowner.sql if [ "$EXECUTE" = "TRUE" ];then > $FIL_EXECUTE fi $SETXV # .................................... # Create the stattab table is required # .................................... if [ "$CREATE_STATTAB" = "TRUE" ];then sqlplus -s "$CONNECT_STRING"<> $FIL_EXECUTE do_execute fi exit fi #pol # .................................... # Export/import STATS # .................................... if [ "$EXPORT_STAT" = "TRUE" -o "$IMPORT_STAT" = "TRUE" ];then #set -x if [ "$EXPORT_STAT" = "TRUE" ];then IMXP=export else IMXP=import fi if [ "$fpart" = "NULL" ];then ST_PART=",partname=>NULL" else ST_PART=",partname=>'$fpart'" fi if [ "$STAT_SYSTEM" = "TRUE" ];then PROC=${IMXP}_system_stats # import_system_stats or export_system_stats elif [ -n "$ftable" ];then G_FTABLE="tabname=> '$ftable' ," G_CASCADE="cascade=> $fcasc ," G_OWNER="ownname=>'$fowner' ," PROC=${IMXP}_table_stats SQL="exec dbms_stats.${IMXP}_table_stats( ownname=>'$fowner', tabname=> '$ftable' $ST_PART, cascade=> $fcasc $METHOD_OPT $COPY_ST_STTAB) " echo "Doing $SQL" sqlplus -s "$CONNECT_STRING"< abort" fi exit fi # ******************************************************** # ******************************************************** # Gather stats for TABLE,INDEX or SCHEMA # ******************************************************** # # ******************************************************** # A) Gather stats for TABLE # ******************************************************** if [ -n "$ftable" ];then #set -x # .................................... # check if we will gather stats only # for some columns # .................................... if [ -n "$COL_LIST" ];then METHOD_OPT=", method_opt => 'For columns ${COL_LIST}'," fi # .................................... # check if table is not partitioned : # .................................... var=`sqlplus -s "$CONNECT_STRING"<> $FIL_EXECUTE fi done else # ............................................. # No partitions or single (sub)pationtion # ............................................. if [ -n "$l_part" ];then ST_PARTNAME="partname=> '$l_part'," fi SQL="exec dbms_stats.gather_table_stats( ownname=>'$fowner', tabname=> '$ftable' Degree=> $fdegree, $ST_PARTNAME estimate_percent=> $fperc, granularity=>'$fgran', cascade=>$fcasc $COPY_ST_STTAB $METHOD_OPT) " echo $SQL if [ "$EXECUTE" = "TRUE" ];then echo $SQL >> $FIL_EXECUTE fi fi # ******************************************************** # B) INDEX # ******************************************************** elif [ -n "$findex" ];then # index # .................................... # check if Index is not partitioned : # .................................... var=`sqlplus -s "$CONNECT_STRING"<" exit 0 fi else PART_NAME=PARTITION_NAME DBA_TAB=DBA_IND_PARTITIONS fi # ............................................. # loop on partitions now to issue the statement # ............................................. LST_PART=`sqlplus -s "$CONNECT_STRING"<> $FIL_EXECUTE fi done else # ............................................. # No partitions # ............................................. if [ -n "$l_part" ];then ST_PARTNAME="partname=> '$l_part'," fi SQL="exec dbms_stats.gather_index_stats( ownname=>'$fowner', indname=> '$findex', $ST_PARTNAME estimate_percent=> $fperc $COPY_ST_STTAB) " echo $SQL if [ "$EXECUTE" = "TRUE" ];then echo $SQL >> $FIL_EXECUTE fi fi else SQL="exec dbms_stats.gather_schema_stats( ownname=>'$fowner', Degree=> $fdegree, estimate_percent=> $fperc $COPY_ST_STTAB) " echo $SQL if [ "$EXECUTE" = "TRUE" ];then echo $SQL >> $FIL_EXECUTE fi fi if [ "$EXECUTE" = "TRUE" ];then do_execute fi