说明:所有的脚本都是基于DB2 UDB V8.2编写的,在AIX5.3的默认SHELL下运行,如果要移植到其他操作系统需要适当调整里面的语法。
由于我们用的是V82的DB2,也没怎么研究DB2自己的自动RUNSTATS维护,所以就自己整了一个脚本更新表的统计信息,顺便对存储过程的包更新执行计划、重新绑定。刚开始的时候只有一个数据库,脚本写的比较简单,后来数据库一多起来就只好改进脚本。原理很简单,从SYSCAT.TABLES里面选出类型是'T'和'S'的表,同时剔除个别不需要更新统计值的表,按照固定的格式生成RUNSTATS语句。对存储过程的包也是用相似的方法,不过数据从SYSCAT.PACKAGES来。
脚本的调用必须传三个参数,位置都是固定的,分别是数据库名,用户名,密码。
我对自己现在的RUNSTATS语句模板也不是很有把握。"RUNSTATS ON TABLE tabname WITH DISTRIBUTION ON ALL COLUMNS AND INDEXES ALL",选择了这些参数足够吗?
由于现在的数据库数据量都比较少,没有超过100GB的,所以现在都是每天用这个脚本更新统计值。想了解几百GB甚至是TB级别的数据库,统计值更新的策略一般是怎样的?
之前有老大提到DPF的环境,这里完全没有考虑DPF的情形。请了解DPF的朋友介绍一下在分区环境下更新统计值有什么需要注意的。
如果大家有更好的方法或者想法,请不吝赐教。
欢迎转发试用,转贴请注明出处。谢谢!
##############################################
#r.sh DBNAME USER PASS
. $HOME/sqllib/db2profile
DBNAME=$1
USER=$2
PASS=$3
LOG=~/mon/runstats.$DBNAME.log
SQL=~/mon/runstats.$DBNAME.sql
date +%Y-%m-%d.%H:%M:%S > $LOG
db2 connect to $DBNAME user $USER using $PASS >> $LOG
echo "connect to $DBNAME user $USER using $PASS ;" > $SQL
db2 "select 'RUNSTATS ON TABLE ' || ltrim(rtrim(tabschema)) || '.' || ltrim(rtrim(tabname)) || ' WITH DISTRIBUTION ON ALL COLUMNS AND INDEXES ALL ;' from syscat.tables where type in ('S', 'T') and tabname not in ('TB_LOG') order by npages desc" | grep -i "RUNSTATS" >> $SQL
db2 "select 'REBIND ' || ltrim(rtrim(pkgschema)) || '.' || ltrim(rtrim(pkgname)) || ' ;' from syscat.packages where pkgschema not in ('NULLID') order by last_bind_time" | grep -i "^REBIND" >> $SQL
echo "disconnect all ;" >> $SQL
echo RUNSTATS AND REBIND START >> $LOG
date +%Y-%m-%d.%H:%M:%S >> $LOG
db2 -tvf $SQL >> $LOG
echo RUNSTATS AND REBIND END >> $LOG
date +%Y-%m-%d.%H:%M:%S >> $LOG
##############################################
由于我们用的是V82的DB2,也没怎么研究DB2自己的自动RUNSTATS维护,所以就自己整了一个脚本更新表的统计信息,顺便对存储过程的包更新执行计划、重新绑定。刚开始的时候只有一个数据库,脚本写的比较简单,后来数据库一多起来就只好改进脚本。原理很简单,从SYSCAT.TABLES里面选出类型是'T'和'S'的表,同时剔除个别不需要更新统计值的表,按照固定的格式生成RUNSTATS语句。对存储过程的包也是用相似的方法,不过数据从SYSCAT.PACKAGES来。
脚本的调用必须传三个参数,位置都是固定的,分别是数据库名,用户名,密码。
我对自己现在的RUNSTATS语句模板也不是很有把握。"RUNSTATS ON TABLE tabname WITH DISTRIBUTION ON ALL COLUMNS AND INDEXES ALL",选择了这些参数足够吗?
由于现在的数据库数据量都比较少,没有超过100GB的,所以现在都是每天用这个脚本更新统计值。想了解几百GB甚至是TB级别的数据库,统计值更新的策略一般是怎样的?
之前有老大提到DPF的环境,这里完全没有考虑DPF的情形。请了解DPF的朋友介绍一下在分区环境下更新统计值有什么需要注意的。
如果大家有更好的方法或者想法,请不吝赐教。
欢迎转发试用,转贴请注明出处。谢谢!
##############################################
#r.sh DBNAME USER PASS
. $HOME/sqllib/db2profile
DBNAME=$1
USER=$2
PASS=$3
LOG=~/mon/runstats.$DBNAME.log
SQL=~/mon/runstats.$DBNAME.sql
date +%Y-%m-%d.%H:%M:%S > $LOG
db2 connect to $DBNAME user $USER using $PASS >> $LOG
echo "connect to $DBNAME user $USER using $PASS ;" > $SQL
db2 "select 'RUNSTATS ON TABLE ' || ltrim(rtrim(tabschema)) || '.' || ltrim(rtrim(tabname)) || ' WITH DISTRIBUTION ON ALL COLUMNS AND INDEXES ALL ;' from syscat.tables where type in ('S', 'T') and tabname not in ('TB_LOG') order by npages desc" | grep -i "RUNSTATS" >> $SQL
db2 "select 'REBIND ' || ltrim(rtrim(pkgschema)) || '.' || ltrim(rtrim(pkgname)) || ' ;' from syscat.packages where pkgschema not in ('NULLID') order by last_bind_time" | grep -i "^REBIND" >> $SQL
echo "disconnect all ;" >> $SQL
echo RUNSTATS AND REBIND START >> $LOG
date +%Y-%m-%d.%H:%M:%S >> $LOG
db2 -tvf $SQL >> $LOG
echo RUNSTATS AND REBIND END >> $LOG
date +%Y-%m-%d.%H:%M:%S >> $LOG
##############################################
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/10990946/viewspace-693964/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/10990946/viewspace-693964/