====== Tables, Indexes, Partitions, Objects ======
===== Tables =====
**Show table size and organization (10.5) :**
db2 "select varchar(t.tabschema,15) as tabschema, varchar(t.tabname,40) as tabname
, COL_OBJECT_P_SIZE/1024 as col_size_mb
, DATA_OBJECT_P_SIZE/1024 as data_size_mb
, INDEX_OBJECT_P_SIZE/1024 as index_size_mb
, (LONG_OBJECT_P_SIZE + LOB_OBJECT_P_SIZE + XML_OBJECT_P_SIZE)/1024 as lob_size_mb
, tableorg from syscat.tables t join sysibmadm.admintabinfo ati on t.tabname=ati.tabname and t.tabschema=ati.tabschema where t.type='T'
and t.tabschema not like ('SYS%') order by 3 desc with ur"
**Show table size and organization ( > 9.7 ) :**
db2 "select substr(t.tabschema,1,18) as tabschema
, substr(t.tabname,1,40) as tabname
, DATA_OBJECT_P_SIZE/1024 as tab_size_mb
, INDEX_OBJECT_P_SIZE/1024 as idx_size_mb
from syscat.tables t
join sysibmadm.admintabinfo ati
on t.tabname=ati.tabname
and t.tabschema=ati.tabschema
where t.type='T'
and t.tabschema not like ('SYS%')
order by 3 desc
with ur"
**Table size (old and slow) :**
db2 "SELECT SUBSTR(TabSchema,1,15) TabSchema, SUBSTR(TabName,1,15), TabType,
(Data_Object_P_Size + Index_Object_P_Size + Long_Object_P_Size + Lob_Object_P_Size + Xml_Object_P_Size)/1024 as Total_P_Size_MB
FROM SysIbmAdm.AdminTabInfo ORDER BY Total_P_Size_MB"
**Query table space of particular tables :**
db2 "select a.TBSPACEID,substr(b.TBSP_NAME,1,40) TBSP_NAME, substr(a.tabname,1,20) TABNAME
from syscat.tables a join SYSIBMADM.SNAPTBSP b on a.TBSPACEID = b.TBSP_ID
where a.tabschema = 'DB2INST1' and a.tabname in ('TBS1TB1','TBS1TB2','TBS2TB1')"
**Show me dependent objects on TABLE :**
db2 "call dbms_utility.get_dependency('TABLE',,)"
**Show me tables with LOB/XML columns :**
db2 "select varchar(tabname,20) table,varchar(colname,30) column,varchar(typename,20) type from syscat.columns where tabschema = 'DATAUSER' and typename like '%LOB%' or typename like '%XML' order by tabname with ur"
**RR :**
db2 "SELECT current timestamp, varchar(tabschema,20) as tabschema,
varchar(tabname,20) as tabname,
sum(rows_read) as total_rows_read,
sum(rows_inserted) as total_rows_inserted,
sum(rows_updated) as total_rows_updated,
sum(rows_deleted) as total_rows_deleted,
sum(table_scans) as total_table_scans
FROM TABLE(MON_GET_TABLE('MAXIMO','MP2INT_BUFFER',-2)) AS t
GROUP BY tabschema, tabname
ORDER BY total_rows_read DESC"
db2 "SELECT current timestamp, VARCHAR(S.INDSCHEMA, 20) AS INDSCHEMA,
VARCHAR(S.INDNAME, 20) AS INDNAME,
T.DATA_PARTITION_ID,
T.MEMBER,
T.INDEX_SCANS,
T.INDEX_ONLY_SCANS
FROM TABLE(MON_GET_INDEX('MAXIMO','MP2INT_BUFFER', -2)) as T, SYSCAT.INDEXES AS S
WHERE T.TABSCHEMA = S.TABSCHEMA AND
T.TABNAME = S.TABNAME AND
T.IID = S.IID
ORDER BY INDEX_SCANS DESC"
===== Packages =====
** Find package for stored procedure :**
db2 "select r.routineschema, r.routinename, rd.bschema as packageschema, rd.bname as packagename from syscat.routines r, syscat.routinedep rd where r.specificname=rd.specificname and r.routineschema=rd.routineschema and rd.btype='K' and r.routineschema = 'DATAUSER' and upper(r.routinename) = 'REVERSEINVENTORY' with ur"
** Rebind packages for procedures : **
db2 -x "select distinct 'rebind package ' || rtrim(rd.bschema) || '.' || rtrim(rd.bname) || ';' from syscat.routines r, syscat.routinedep rd where r.specificname=rd.specificname and r.routineschema=rd.routineschema and rd.btype='K' and r.routineschema = 'DATAUSER' with ur" | sed 's/ //g'
===== Views =====
**Extract DDL for existing view : **
db2 "select listagg(column_name,',') within group(order by ordinal_position) from sysibm.columns where table_name = 'VIEW1' group by table_name"
==== DDL ====
**Generate DDL for table :**
db2look -d MY_DDBB -t DEPT -a -e -x -o FILE_OUT.txt
==== Invalid objects ====
Admin View : SYSCAT.INVALIDOBJECTS : For Finding Invalid DB Objects.
Admin Proc : SYSPROC.ADMIN_REVALIDATE_DB_OBJECTS : For Fixing Invalid DB Objects.
**Show invalid objects :**
db2 "select substr(objectschema,1,20) SCHEMA, substr(objectname,1,70) OBJECT, case objecttype when 'B' then 'Trigger' when 'F' then 'Routine' when 'R' then 'User datatype' when 'V' then 'View' when 'v' then 'Global var' when 'y' then 'Row perm.' when 2 then 'Col. mask' when 3 then 'Usage list' end as Type from syscat.invalidobjects with ur"
**Soft invalidation (ON by default) :**
db2set DB2_DDL_SOFT_INVAL
**Revalidate invalid objects :**
db2 "ADMIN_REVALIDATE_DB_OBJECTS"
==== Table compression ====
**Create/enable row compression :**
db2 "create table
RESETDICTIONARY"
#keep the compression
db2 "reorg table
KEEPDICTIONARY
**Inspect table for estimated row compression :**
db2 "inspect rowcompestimate table name
schema results keep inspect_
.out"
# format the output to readable form by :
db2inspf inspect_
.out db2inspect_out.txt
**Compression estimation :**
SELECT * FROM TABLE(SYSPROC.ADMIN_GET_TAB_COMPRESS_INFO(', '
'))
===== Index =====
**Asynchronous index cleanup for MDC tables :**
db2set DB2_MDC_ROLLOUT=DEFER
#or
SET CURRENT MDC ROLLOUT MODE
**Index usage :**
db2 "SELECT VARCHAR(S.INDSCHEMA, 20) AS INDSCHEMA, VARCHAR(S.INDNAME, 20) AS INDNAME,T.INDEX_SCANS,T.INDEX_ONLY_SCANS FROM TABLE(MON_GET_INDEX('MM_EDW','ACQ_GG', -2)) as T,SYSCAT.INDEXES AS S WHERE T.TABSCHEMA = S.TABSCHEMA AND T.TABNAME = S.TABNAME AND T.IID = S.IID ORDER BY INDEX_SCANS DESC with ur"
**Index keysize vs. table row size :**
db2 "select
substr(t.TABNAME,1,12) as tabname
, substr(i.INDNAME,1,20) as indnameA
, AVGROWSIZE as RSIZE
, AVGLEAFKEYSIZE as KSIZE
, 100*(DECIMAL((FLOAT(AVGLEAFKEYSIZE)/FLOAT(AVGROWSIZE)),7,5)) as PCT_OF_ROWSIZE
from syscat.indexes i, syscat.tables t
where i.tabschema=t.tabschema and i.tabname=t.tabname
and type='T'
and AVGROWSIZE>0
and t.tabname='STOCK_GG_FACT_NEW'
and t.tabschema='MM'
order by PCT_OF_ROWSIZE desc
with ur"
==== Index compression ====
Not supported in block indexes and XML path indexes
Index specifications cannot be compressed
Compression attributes for indexes on temp. tables cannot be altered
**Enable Index compression :**
db2 "create index ... COMPRESS YES"
db2 "alter index ... COMPRESS YES"
# enable compression by reorganization of the index
**Disable index compression :**
db2 "alter index ... COMPRESS NO"
# disable compression by reorganization of the index
**INVALID indexes :**
db2 "select varchar(tabname,25) table, varchar(indname,25) index, index_requires_rebuild from table(sysproc.admin_get_index_info('','MM','STOCK_FI_MESE_ST_FACT')) as t with ur"
**IX_STATS :**
db2 "select varchar(index_name,20) index,INDCARD,NLEAF,NUM_EMPTY_LEAFS,NLEVELS,NUMRIDS_DELETED,FULLKEYCARD,LEAF_PAGE_OVERHEAD,F4,F5,F6,F7,F8, REORG from session.ix_stats"
===== MQT =====
**Query dependencies for MQT :**
db2 "select substr(tabname,1,24) as tabname, dtype, substr(bname,1,24) as bname, btype from syscat.tabdep where tabschema = 'MELNYK' and dtype = 'S'"
**MQT Staging tables **:
- Create MQT (data initially deffered refresh deffered);
- create table stage for mqt propagate immediate in ;
===== Runstats/Reorg =====
**Monitor reorg progress :**
db2 "select
varchar(tabname, 40) as tab_name,
reorg_phase,
substr(reorg_type, 1, 70) as reorg_type,
reorg_status,
reorg_completion
from sysibmadm.snaptab_reorg
order by tabname with ur"
**Check for automatic runstats/reorgs of all DBs:**
for db in `db2 list db directory | grep -p Indirect| grep alias | awk '{print $NF}'`; do echo "------ $db ------" && db2 get db cfg for $db | egrep "AUTO_RUNSTATS|AUTO_REORG|AUTO_TBL_MAINT|AUTO_MAINT" && echo && echo; done
**Generate scripts for reorg of tables, indexes and runstats** :
db2 "list tables for all" | awk '{print $2"." $1}' | awk '/\w/ {print $0}' | sed '/^Schema.Table/d' | sed '/^record(s)./d' | sed 's/^/REORG TABLE /g' | sed 's/$/;/g' > /tmp/reorg_tbl.ddl
db2 "list tables for all" | awk '{print $2"." $1}' | awk '/\w/ {print $0}' | sed '/^Schema.Table/d' | sed '/^record(s)./d' | sed 's/^/REORG INDEXES ALL FOR TABLE /g' | sed 's/$/;/g' > /tmp/reorg_idx.ddl
db2 "list tables for all" | awk '{print $2"." $1}' | awk '/\w/ {print $0}' | sed '/^Schema.Table/d' | sed '/^record(s)./d' | sed 's/^/RUNSTATS ON TABLE /g' | sed 's/$/ WITH DISTRIBUTION AND DETAILED INDEXES ALL;/g' > /tmp/runstats_tbl.ddl
db2 -tvf /tmp/reorg_tbl.ddl
db2 -tvf /tmp/reorg_idx.ddl
db2 -tvf /tmp/runstats_tbl.ddl
**Statistical Views :**
* Create view for statistics which matches the Join query
* Cannot have : aggregations or distinct,
create view .. enable for optimization
* Enable it for runstats
**REORG for NON-SYS :**
db2 -x "select 'REORG TABLE ' ||rtrim (tabschema)|| '.' || rtrim (tabname) || ' ;' from syscat.tables where tabschema not like 'SYS%' and type = 'T'"
**RUNSTATS for NON-SYS :**
db2 -x "select 'RUNSTATS ON TABLE ' ||rtrim (tabschema)|| '.' || rtrim (tabname) || ' WITH DISTRIBUTION ON ALL COLUMNS AND DETAILED INDEXES ALL ALLOW WRITE ACCESS;' from syscat.tables where tabschema not like 'SYS%' and type = 'T'" > runstats.sql
**Reorgchk : **
db2 "select substr(table_schema,1,18) as tabschema, substr(table_name,1,30) as tabname, f1, f2, f3, reorg from SESSION.TB_STATS"
**Offline reorg :**
1. Call reorgchk procedure to check the statistics :
db2 "call sysproc.reorgchk_tb_stats('T','ALL')"
2. Generate reorg script for needed tables (* in F1/F2 or F3 formulas) :
db2 -x "select 'reorg table ' || rtrim(table_schema) || '.' || rtrim(table_name) || ';' from session.tb_stats where table_schema not like 'SYS%' and reorg like '%*%' order by reorg" > reorg_needed.sql
3. Generate reorg script for optional tables (nothing in F1/F2 or F3 formulas) :
db2 -x "select 'reorg table ' || rtrim(table_schema) || '.' || rtrim(table_name) || ';' from session.tb_stats where table_schema not like 'SYS%' and reorg not like '%*%' order by reorg" > reorg_optional.sql
4. Generate runstats script for all reorganized tables
db2 -x "select 'runstats on table ' || rtrim(table_schema) || '.' || rtrim(table_name) || ' with distribution on all columns and detailed indexes all;' from session.tb_stats where table_schema not like 'SYS%' order by reorg" > runstats_all.sql
5. Launch the scripts
db2 -tvf reorg_needed.sql | tee -a reorg_needed.out
db2 -tvf reorg_optional.sql | tee -a reorg_optional.out
db2 -tvf runstats_all.sql | tee -a runstats_all.out
6. Rebind all packages (valid and invalid)
db2rbind -l rebind_all.out all
**Monitor progress of Reorg :**
db2 "select substr(tabname, 1, 15) as tab_name, substr(tabschema, 1, 15) as tab_schema, reorg_phase,
substr(reorg_type, 1, 20) as reorg_type, reorg_status, reorg_completion, dbpartitionnum
from sysibmadm.snaptab_reorg order by dbpartitionnum"
or
db2pd -d -reorg
===== Partitions =====
**Check for table partitions :**
db2 "select substr(DATAPARTITIONNAME,1,20) as partition_name, substr(TABSCHEMA,1,8) as tabschema, substr(TABNAME,1,15) as tabname,
(select substr(tbsp_name,1,15) from sysibmadm.snaptbsp where tbsp_id=TBSPACEID) as TABLE_TBSP, (select substr(tbsp_name,1,15) from sysibmadm.snaptbsp where tbsp_id=INDEX_TBSPACEID) as INDEX_TBSPACE, (select substr(tbsp_name,1,15) from sysibmadm.snaptbsp where tbsp_id=LONG_TBSPACEID) as LONG_TBSP, substr(lowvalue,1,10) as lowvalue, substr(highvalue,1,10) as highvalue, LOWINCLUSIVE, HIGHINCLUSIVE, card from SYSCAT.DATAPARTITIONS where tabname = 'TBWCSATS' order by DATAPARTITIONNAME"
**Add new partition :**
db2 "alter table DWCO.TBWCFPAG add partition "part2015" starting from ('2015-02-01') ending ('2016-01-31') in TSDATI78 index in TSIDX078"
**Detach partition & delete :**
db2 "alter table detach partition into "
db2 "drop table
===== Referential Integrity =====
**Query constraints on tables :**
db2 "select char(constname,30) const, char(tabschema,8) schema,char(tabname,30) table,char(REFTABSCHEMA,8) schem,char(REFTABNAME,30) reftab,char(FK_COLNAMES,30) refCOL,char(PK_COLNAMES,30) pkCOL from syscat.references where CONSTNAME = 'F_1145'"
**Disable query optimization :**
db2 "alter table . alter foreign key disable query optimization"
**Query violationg rows from child table (DISABLE QUERY OPTIMIZATION !):**
db2 "(SELECT C. FROM . C) EXCEPT (SELECT P. FROM . P, . C WHERE P. = C.)"
**Enforce constraint :**
db2 "alter table .
alter foreign key enforced"
**Query foreign keys :**
db2 "select
substr(constname,1,30) constname
, substr(tabschema,1,18) tabschema
, substr(tabname,1,20) tabname
, deleterule
from syscat.references
where deleterule != 'C'
with ur"
**Generate statements to redefine RI from restrict to CASCADE :**
db2 "select 'alter table ' || tabschema || '.'
|| TABNAME
|| ' drop constraint '
|| CONSTNAME
|| ';'
|| CHR(10)
|| 'alter table ' || tabschema || '.'
|| TABNAME
|| ' add constraint '
|| CONSTNAME
|| ' foreign key ('
|| (select
SUBSTR(XMLCAST(XMLGROUP(',' || colname AS a) AS VARCHAR(60)), 2)
from syscat.keycoluse k
where k.constname=r.constname
and k.tabschema=r.tabschema
and k.tabname=r.tabname)
|| ') references ' || tabschema || '.'
|| REFTABNAME
|| ' ('
|| (select
SUBSTR(XMLCAST(XMLGROUP(',' || colname AS a) AS VARCHAR(60)), 2)
from syscat.keycoluse k
where k.constname=r.refkeyname
and k.tabschema=r.reftabschema
and k.tabname=r.reftabname)
|| ') on delete cascade;'
from syscat.references r
where DELETERULE != 'C'
and constname in ('FK_GS_CATENT','FK_XDESC_CATENT')
order by TABNAME
with ur"
**Recreate foreing keys as NOT ENFORCED :**
db2 "select 'alter table ' || tabschema || '.'
|| TABNAME
|| ' drop constraint '
|| CONSTNAME
|| ';'
|| CHR(10)
|| 'alter table ' || tabschema || '.'
|| TABNAME
|| ' add constraint '
|| CONSTNAME
|| ' foreign key ('
|| (select
SUBSTR(XMLCAST(XMLGROUP(',' || colname AS a) AS VARCHAR(60)), 2)
from syscat.keycoluse k
where k.constname=r.constname
and k.tabschema=r.tabschema
and k.tabname=r.tabname)
|| ') references ' || tabschema || '.'
|| REFTABNAME
|| ' ('
|| (select
SUBSTR(XMLCAST(XMLGROUP(',' || colname AS a) AS VARCHAR(60)), 2)
from syscat.keycoluse k
where k.constname=r.refkeyname
and k.tabschema=r.reftabschema
and k.tabname=r.reftabname)
|| ') on delete cascade not enforced;'
from syscat.references r
where tabschema = 'CTGINST1'
order by TABNAME
with ur"
===== Export/Import/Load/Ingest =====
**Check integrity pending states :**
db2 "select tabname,
substr(const_checked,1,1)
substr(const_checked,2,1)
substr(const_checked,5,1)
substr(const_checked,6,1)
substr(const_checked,7,1)
from syscat.tables
where status='C'"
**Export data :**
db2 "export to .ixf of ixf "
**Load data from export :**
db2 "load from .ixf of ixf replace into .
"
**Table in Load Pending :**
db2 "load from /dev/null of del terminate into .
copy yes to /dev/null"
**Generate SET INTEGRITY in correct chain order :**
db2 -x "with TABLIST(fullname,seqno) as
(select rtrim(tabschema)||'.'||tabname,
rownumber() over (order by tabschema||tabname)
from syscat.tables
where STATUS = 'C'),
SERIAL_LIST(s_fullname,s_seqno) as
(select long_varchar(rtrim(fullname)),
seqno
from tablist
where seqno = 1
UNION ALL
select long_varchar(rtrim(s_fullname||','||fullname)),
seqno
from tablist t, serial_list s
where s.s_seqno +1 = t.seqno )
select rtrim('set integrity for '|| s_fullname || ' immediate checked;')
from ( select s_fullname,
s_seqno,
rownumber() over (order by s_seqno desc) as rownum
from serial_list) as zzzzz
where rownum = 1" | egrep -v "SQL0347W|infinite" > SET_INTEGRITY_CHAIN.sql
**Load from cursor :**
db2 "declare REFRESH cursor database user using for select