RUNSTATS teaches the DB2 optimizer what your data looks like—how many rows, how skewed the columns are, and how selective the indexes feel. This hands-on tutorial shows prerequisites, a practical control statement and JCL, how to verify catalog updates, and common mistakes after loads and deletes.
Every bind and dynamic prepare is a guessing game unless the catalog holds good statistics. RUNSTATS samples or reads objects and stores cardinalities, null counts, frequency values, histograms, and index metrics. Without that information—or with numbers from last year—Db2 may pick a tablespace scan when an index would win, or the reverse.
RUNSTATS does not reorganize pages. If rows are physically messy, run REORG (often with inline STATISTICS). If rows are fine but the optimizer is blind, run RUNSTATS. After a bulk LOAD, both concerns often appear together.
Whole table space, specific partitions, specific tables, or indexes only—match the scope to what changed. After loading one partition, partition-level RUNSTATS may be enough.
123456RUNSTATS TABLESPACE TRAINING.EMPTS TABLE(ALL) INDEX(ALL) KEYCARD HISTOGRAM NUMQUANTILES 100 SHRLEVEL CHANGE
A lighter teaching example:
123RUNSTATS TABLESPACE TRAINING.EMPTS TABLE(TRAINING.EMPLOYEE) INDEX(ALL)
Option meanings beginners should know:
Compared with REORG, RUNSTATS JCL is often smaller—no sort of reloaded rows—though large shops still wrap it in standard PROCs.
12345678910111213141516//RUNSTEMP JOB (ACCT),'DB2 RUNSTATS',CLASS=A,MSGCLASS=X, // NOTIFY=&SYSUID //JOBLIB DD DISP=SHR,DSN=DSN.V13R1M0.SDSNEXIT // DD DISP=SHR,DSN=DSN.V13R1M0.SDSNLOAD //RUNSTATS EXEC PGM=DSNUTILB,REGION=0M, // PARM='DB2T,RUNSTEMP' //SYSPRINT DD SYSOUT=* //UTPRINT DD SYSOUT=* //SYSUDUMP DD SYSOUT=* //SYSIN DD * RUNSTATS TABLESPACE TRAINING.EMPTS TABLE(ALL) INDEX(ALL) KEYCARD SHRLEVEL CHANGE /*
Confirm the utility processed the intended objects and completed with an acceptable return code. Save SYSPRINT in change records when the run supports a production promotion.
Dynamic SQL picks up new stats on new prepares (subject to caching). Static packages may keep old paths until REBIND. Many sites rebind critical plans after significant RUNSTATS on large tables.
STATSTIME on SYSTABLESPACE / SYSINDEXES (and related catalog tables) refreshed to the run time123456789101112SELECT NAME, NTABLES, STATSTIME FROM SYSIBM.SYSTABLESPACE WHERE DBNAME = 'TRAINING' AND NAME = 'EMPTS'; SELECT NAME, FIRSTKEYCARDF, FULLKEYCARDF, STATSTIME FROM SYSIBM.SYSINDEXES WHERE TBCREATOR = 'TRAINING' AND TBNAME = 'EMPLOYEE'; SELECT COUNT(*) AS LIVE_ROWS FROM TRAINING.EMPLOYEE;
Missing RUNSTATS privilege yields utility authorization errors. Request the privilege or run under an ID your security model allows for DDL/utility work.
Database/table space typos are common when copying JCL. Prefetch names from the catalog.
Running RUNSTATS against a 100-row subset then promoting volumes to millions leaves misleading stats if you do not collect again at production scale.
Row counts and distributions changed completely, but the optimizer still believes old numbers—or sees incomplete inline stats. Always confirm STATSTIME after bulk loads.
Some utilities conflict on the same target. DISPLAY UTILITY and serialize maintenance.
Bad cluster ratios need REORG. RUNSTATS alone cannot put rows back in order.
Db2 is a librarian who decides which shelf to check first. RUNSTATS is counting how many books are red, how many are blue, and which shelves are crowded so the librarian can guess faster. If you dump in a thousand new books and forget to recount, the librarian still thinks the shelves look like yesterday and may walk to the wrong place. REORG is tidying the shelves; RUNSTATS is updating the inventory card.
1. What is the main purpose of RUNSTATS?
2. Does RUNSTATS reclaim fragmented space like REORG?
3. What does TABLE(ALL) INDEX(ALL) ask RUNSTATS to do?
4. How do you verify RUNSTATS worked?
5. When might inline statistics replace a standalone RUNSTATS?