DB2的包

DB2的package包含了可以执行的代码,可以认为就是访问计划,包的rebind和其他数据库(MSSQL, Sybase and Oracle)中的recompile是一个意思。

查看有哪些包
--- ALL packages: db2 list package for all
select pkgname, pkgschema, pkgversion, unique_id, boundby,reoptvar, total_sect,valid, format, isolation, blocking
from syscat.packages
order by pkgschema, pkgname, pkgversion;

--- Package own by NULLID schema: db2 list package for system
select pkgname, pkgschema, pkgversion, unique_id, boundby,reoptvar, total_sect,valid, format, isolation, blocking
from syscat.packages
where pkgschema = 'NULLID'
order by pkgschema, pkgname, pkgversion;

-- Packages own by user: db2 list package
select pkgname, pkgschema, pkgversion, unique_id, boundby,reoptvar, total_sect,valid, format, isolation, blocking
from syscat.packages
where pkgschema = USER
order by pkgschema, pkgname, pkgversion;

db2 list packages for all

存储过程,函数都会产生包,这里有必要介绍一下REOPTVAR这个列,它表示这个包每次执行是否会被重新优化,为什么要重新优化那?因为存储过程,函数都可能有输入变量
基于不同的输入变量,这个包的执行计划可能大不相同,所以重新优化能够产生更好的执行计划,但是重新优化是要花费代价的,这里需要用户来指定是否需要重新优化,REOPTVAR其值有三:
A = Access path is re optimized for every OPEN or EXECUTE request
N = Access path is determined at bind time
O = Access path is re optimized only at the first OPEN or EXECUTE request; it is subsequently cached

A - Always, N - Never, O - Once
根据这几个英语单词的意思不难理解,A表示每次都优化,N表示bind以后就不会做优化,O表示在第一次执行的时候优化,以后的执行都使用第一次执行生成的执行计划,我们马上可以理解到如果第一次执行生成的执行计划不具有代表性,那么后续的执行会收到一定的影响

Valid这个列表示这个包现在是否是有效的,如果它的值为N,那么就表示此包无效,需要rebind
在做rebind的时候,如果这个包正在被使用,那么需要等待,因为rebind的时候需要持有排他锁(exclusive lock)
SELECT PKGNAME, PKGSCHEMA, PKGVERSION, UNIQUE_ID, BOUNDBY, REOPTVAR,
  TOTAL_SECT, CREATE_TIME, EXPLICIT_BIND_TIME, LAST_BIND_TIME,
  VALID, FORMAT, ISOLATION, BLOCKING
  FROM SYSCAT.PACKAGES
  WHERE PKGNAME = 'P5582207';

rebind的方法很简单,命令行方式的是使用包名
db2 rebind P1234567 reopt once

另外可以调用一个存储过程SYSPROC.REBIND_ROUTINE_PACKAGE来做rebind,这种方式需要存储过程的名字,可以用下面的SQL来获取存储过程的名字
SELECT DISTINCT A.ROUTINENAME, B.BNAME FROM SYSCAT.ROUTINES A,
SYSCAT.ROUTINEDEP B, SYSCAT.PACKAGES C WHERE
B.ROUTINENAME = A.SPECIFICNAME AND B.BNAME = C.PKGNAME AND C.PKGNAME = 'P1234567'

CALL SYSPROC.REBIND_ROUTINE_PACKAGE ('P','HOUSEKEEP1','RESOLVE ANY REOPT ONCE APREUSE YES')

我们有时候可能需要rebind所有invalid的package
db2rbind sample  -l /tmp/rebindall.log
rebind所有的package
db2rbind sample  -l /tmp/rebindall.log all

如果想查看package cache里面的信息,可以调用一个存储过程
db2 "call monreport.pkgcache"
-- Last 30 mins
db2 "call monreport.pkgcache(30)"

请使用浏览器的分享功能分享到微信等