2007-3-24 15:28
beginner-bj
捕获引起表扫描的SQL语句
本文引自我的BLOG [url=http://blog.chinaunix.net/u/739/showart.php?id=264204]http://blog.chinaunix.net/u/739/showart.php?id=264204[/url]
捕获引起表扫描的SQL语句
昨天晚上接到公司的电话,有用户报数据库查询太慢。检查了一下,发现原因是索引建得不合理,很多语句都在做表扫描。为了能以后及时处理类似问题,写下如下脚本:
DBNAME=eware
db2 connect to $DBNAME
db2pd -lock -db $DBNAME > /tmp/pdLock
awk '$4 == "Table" && $1 ~ /^0x/ {print $(NF-4)}' /tmp/pdLock | sort | uniq >/tmp/pdTranHdl
if [ -s /tmp/pdTranHdl ]
then
db2pd -active -db $DBNAME > /tmp/pdActive
db2pd -trans -db $DBNAME > /tmp/pdTrans
db2pd -dyna -db $DBNAME > /tmp/pdDyna
cat /tmp/pdTranHdl | while read TranHdl
do
echo TranHdl $TranHdl
awk '$4 == TranHdl && $1 ~ /^0x/ {print $2}' TranHdl=$TranHdl /tmp/pdTrans | read AppHandl
echo AppHandl $AppHandl
db2 get snapshot for application agentid $AppHandl | egrep '(Co.*timestamp|Sn.*timestamp)'
db2 list applications show detail | grep $AppHandl
awk '$2 == AppHandl && $1 ~ /^0x/ {print $6,$7}' AppHandl=$AppHandl /tmp/pdActive | read AnchID StmtUID
echo AnchID StmtUID $AnchID $StmtUID
sed -n "/ $AnchID *$StmtUID .*SELECT/,/^0x/{p;}" /tmp/pdDyna \
| sed "s/0x.*$AnchID *$StmtUID.*[0-9] //" | sed 's/^0x.*$/;/' \
| sed -e 's/SELECT/\&SELECT\& /' -e 's/FROM/\&FROM\& /' -e 's/WHERE/\&WHERE\& /' |tr '&' '\n'
done
fi
命令效果如下:
TranHdl 22
AppHandl 1147
Connection request start timestamp = 03/24/2007 14:35:09.754759
Connect request completion timestamp = 03/24/2007 14:35:09.754887
Snapshot timestamp = 03/24/2007 14:41:03.953095
EWUSER das.exe 1147 G9B5B0C0.O307.032FC4063552 0006 1 0 1040624 UOW Executing Not Collected EWARE /home/ewadmin/ewadmin/NODE0000/SQL00001/
AnchID StmtUID 18 245
SELECT
AL2.MFG_ORDER_ID,
AL2.PRODUCT_ID, AL2.QUANTITY_RELEASED, AL2.QUANTITY_COMPLETED, AL2.QUANTITY_IN_PROC, AL1.CREATE_TIMESTAMP , AL1.STATUS,
AL1.LAST_UPDATE_TIME , AL1.SERIAL_NUM, AL2.REGION, AL1.TIME_END
FROM
USERID.X_UWIP AL1, USERID.X_MFG_ORDER AL2
WHERE
(AL2.MFG_ORDER_ID=AL1.MFG_ORDER_ID) AND (AL2.MFG_LINE_ID='9TC' AND AL1.CREATE_TIMESTAMP>(timestamp(CURRENT
DATE,'00.00.00')-(6)days) AND AL1.STATUS<>'SCRAP ') ORDER BY 1
;
这样所有的引起表扫描的动态SQL语句都会被列出来,再根据时间戳来对那些运行时间很长的语句进行重点分析就可以了。
说明:
1、脚本最后的sed部分,用了太多的管道,效率不高;AIX平台的sed好象也不支持\n,所以不得不用了tr。有脚本高手的话,请多多指教。
2、脚本中主要用到db2pd这个命令,我这台AIX上DB2的版本是8.1.11,其它平台或版本的db2pd命令是否拥有相同的输出格式,未知。
3、还有一个假设——假设所有有问题的SQL语句都是动态的。静态的先不管。
========================================================================
任何形式的转载,请写明出处:
email: [email=beginner@yeah.net]beginner@yeah.net[/email]
blog: [url=http://blog.chinaunix.net/index.php?blogId=739]http://blog.chinaunix.net/index.php?blogId=739[/url] [url=http://www.cublog.cn/u/739/]http://www.cublog.cn/u/739/[/url]
========================================================================