Събиране на статистики.
Тази статия е на моя приятел и колега Евгени Балабанов, който е от хората ностъпвали досто "мотики" и за моя радост написа една малка статийка за този сайт.
Събирането на статистики е досадна, но необходима дейност. Вършим я обикновено в "извънработно време", каквото и да означава това. При наличие на много схеми и на много таблици стандартните средства губят доста време, защото работят последователно върху обектите (таблици и техни индекси).
С цел ускоряване на процеса и по-плътно натоварване на ресурсите можем да пуснем събиране на статистики от няколко схеми паралелно. Следният скрипт създава множество от nohup ... & команди, които стартират паралелно събиране на статистики.
#
# Скрипт за паралелно събиране на статистики от различни схеми
#
# Last update:
# 2009-04-05 Evgueni Balabanov
# Created
sqlplus -s / as sysdba << EOF
set feed off
set head off
set lines 300
set newpage none
set pages 2000
set trimspool on
SCRIT_DIR=/home/oracle/admin
LOG_DIR=${SCRIT_DIR}/logs
spool ${SCRIT_DIR}/gsps.sh
select distinct
'nohup ${SCRIT_DIR}/Gather_schema_statistics.sh' f1
, owner f2
, ' > ${LOG_DIR}/Gather_schema_statistics_for_'||owner||'.log &' f3
from dba_tables t -- от тук, а не от dba_users,
--защото може някои user-и да си нямат таблици
-- where owner [not] in ('AAAA','BBBB')
/
spool off
exit;
EOF
chmod u+x ${SCRIT_DIR}/gsps.sh
${SCRIT_DIR}/gsps.sh
exit
Следва скрипт за събиране на статистики от дадена схема.
===================================
#- Gather_schema_statistics.sh
===================================
#
# Скрипт за събиране на статистики от дадена схема
if [ $# -ne 1 ]
then
echo " Proper usage is: $0 < schema > "
exit 8
fi
# Установяване на обкръжение
. /home/oracle/.profile
# Или някакво друго насочване към
# ORACLE_HOME ORACLE_HOME/bin и ORACLE_SID
SCRIT_DIR=/home/oracle/admin
LOG_DIR=${SCRIT_DIR}/logs
sqlplus / as sysdba << EOF
set timing on
spool ${LOG_DIR}/Gather_schema_statistics_for_${1}
prompt Gathering statistics for $1
begin
-- Малко пълнеж за v$session, да си разпознаваме обработките
DBMS_APPLICATION_INFO.SET_CLIENT_INFO ('Statistics gatherer');
DBMS_APPLICATION_INFO.SET_MODULE ('${0}','');
dbms_application_info.set_action('Gather stats for schema ${1}');
dbms_stats.gather_schema_stats
( OWNNAME=>upper('$1'),
ESTIMATE_PERCENT=>NULL,
METHOD_OPT=>'FOR ALL COLUMNS SIZE 1',
OPTIONS => 'GATHER',
DEGREE=>16, -- тук може да се играе допълнително с
-- паралелизъм, в зависимост от броя процесори
granularity=>'ALL');
end;
/
spool off
exit;
EOF
Този пример е подходящ за малък брой схеми или за мощни сървъри. При 2х16 процесора и съответното количество RAM много успешно се справя с 336 схеми за около 2 часа. При по-скромни ресурси големият брой паралелни процеси може да ни позадръсти. Затова следващият пример ще бъде с контролиран паралелизъм...