CLA96G – Db2 12.1 Foundation (Part 4)

Performance & Tuning Optimization

Db2 v12.1 Course CLA96G Part 4 Focus Optimizer, Indexing, Explain, Stats

Performance & Tuning Optimization

Practical guide for Relational DBAs: when to REORG, how to interpret predicate typology in access plans, how to reveal rewritten predicates, and how Db2 uses distribution statistics (num_freqvalues, num_quantiles) plus column group statistics to estimate selectivity.

REORG decisioning Predicate classification Optimized / rewritten statement Jump Scan / Skip Scan Multi-index access (IXAND / IXOR) RUNSTATS distribution Column group statistics

Quick Reference

Use as your “trainer talk track”
Golden rule
Stats → Plans
Bad statistics produce “perfectly wrong” access plans.
REORG trigger
Physical drift
Overflow, low cluster ratio, pseudo-deletes, sparse pages.
Optimizer truth
Rewrite first
Always analyze the optimized statement, not the original SQL.

Instructor best practice

Teach delegates to: (1) confirm statistics quality, (2) inspect the optimized statement, (3) validate access path operators (TBSCAN/IXSCAN/IXAND/IXOR), then (4) adjust indexes/stats — and only then touch SQL.

1) Determining When to REORG Tables & Indexes

REORG is about restoring physical organization so Db2 can execute logical access paths efficiently. When table rows drift away from index key order (or become fragmented), IXSCAN and range scans can degrade into random I/O storms.

What “physical drift” looks like

Overflow rows, sparse pages after deletes, pseudo-deleted index entries, low cluster ratio, and a growing gap between expected vs actual I/O.

Signal Where you see it Why it matters
Overflow rows rising SYSSTAT.TABLES (overflow) Extra page reads + CPU to chase relocated rows
Cluster ratio low SYSSTAT.INDEXES (cluster_ratio) Range scans become random I/O instead of sequential
Leaf density poor Detailed index stats / REORGCHK More pages to scan → higher I/O
Pseudo-deletes accumulate Index stats / REORGCHK Wasted index space, deeper trees, longer traversals
CLP · REORGCHK recommendations
db2 reorgchk current statistics on table <schema>.<tabname>
db2 reorgchk current statistics on table <schema>.<tabname> and indexes all

Operational caution

REORG changes physical layout → can invalidate assumptions for access patterns and may impact concurrency. Prefer online options where feasible and schedule around peak workload.

SQL · Check key stats (catalog)
-- Table indicators
SELECT tabschema, tabname, npages, fpages, overflow
FROM sysstat.tables
WHERE tabschema = '<SCHEMA>' AND tabname = '<TABNAME>';

-- Index clustering indicator
SELECT indschema, indname, cluster_ratio
FROM sysstat.indexes
WHERE tabschema = '<SCHEMA>' AND tabname = '<TABNAME>';

Instructor decision heuristic

If your workload depends on range scans and cluster ratio drops below a practical threshold (often < ~80% in OLTP), REORG becomes a business decision: trade planned maintenance for unplanned performance incidents.

Link it back to the course

Part 4 emphasizes maintenance activities (RUNSTATS/REORG/REORGCHK) as core DBA tuning levers.

2) Predicate Typology & Access-Plan Stages

Predicate classification governs where (and how efficiently) Db2 can apply filters: early (Stage 1), late (Stage 2 residual), and whether an index can be used for range delimiting. This is a foundational concept in Part 4 Unit 1. :contentReference[oaicite:0]{index=0}

Type Where evaluated Typical impact Common cause
Index SARGable Index Manager Can drive IXSCAN, range delimiting Predicate matches index key structure
Data SARGable Data Manager (Stage 1) Filters early, but might still require table access Predicate format ok, but no suitable index
Residual (Stage 2) RDS / after row fetch Costs CPU + may require fetching non-qualifying rows Non-sargable functions, complex expressions, subqueries

Trainer emphasis

Teach delegates: include all predicates even if residual — filtering in the application layer is a performance anti-pattern.

3) Tools to Reveal Rewritten Predicates (Optimized Statement)

Db2 rewrites SQL aggressively: subquery-to-join, predicate pushdown, transitive closure, OR expansion, constant folding, and more. Therefore, analyze the optimized statement and access plan, not just the original SQL text. :contentReference[oaicite:1]{index=1}

Primary workflow: EXPLAIN → db2exfmt

Use EXPLAIN to capture the plan, then render it with db2exfmt to view the optimized statement and predicate evaluation.

CLP · EXPLAIN + format
-- 1) Ensure explain tables exist (one-time per DB)
-- db2 -tvf EXPLAIN.DDL  (or use db2exmig)

-- 2) Capture an explain for a statement
EXPLAIN PLAN FOR
SELECT * FROM <schema>.<table> WHERE <predicate>;

-- 3) Format the explain output
db2exfmt -d <dbname> -1 -o plan.txt

What to look for in db2exfmt

Optimized Statement, predicate stages, operators (TBSCAN/IXSCAN/IXAND/IXOR), and estimated cardinalities vs filter factors.

Other useful explain surfaces

Depending on your environment and tooling choices, you may also use explain-from-section, packages, and statement caches to validate rewritten predicates.

Tool Use
db2exfmt Readable access plan + optimized statement
EXPLAIN FROM SECTION Explain executed sections (useful for packages/dynamic)
EXPLAIN_ARGUMENT Extra metadata (e.g., DEGREE) and details
Design Advisor (db2advis) Workload-driven index suggestions (lab aligns with Part 4 exercises)

Common mistake

“The SQL looks fine.” — but the optimizer rewrote it, estimated selectivity wrong, and chose TBSCAN. Always verify with explain output.

4) Jump Scan, Skip Scan, and Multi-Index Access

Beyond basic index scans, Db2 can use special access paths when predicates do not perfectly align with the leading index keys, or when multiple indexes can be combined to reduce table access.

Jump / Skip Scan (conceptual)

Used when a predicate targets a non-leading column of a composite index and the leading key has low cardinality. Db2 can iterate distinct leading-key values and “jump” into the index for the secondary key.

SQL · Non-leading predicate example
CREATE INDEX ix_orders ON orders(region, order_date);

-- Predicate only on the non-leading key (order_date)
SELECT *
FROM orders
WHERE order_date = DATE('2026-01-01');

What makes Jump/Skip Scan viable

Leading key has few distinct values; enough selectivity on the non-leading predicate; cost model prefers it over full index scan or TBSCAN.

Multi-index access (IXAND / IXOR)

Db2 can combine multiple indexes on the same table by intersecting or unioning RID lists, then fetching only qualifying rows. This is especially relevant when no single index matches all predicates.

SQL · Multi-index access example
-- Suppose we have:
-- CREATE INDEX ix_region ON orders(region);
-- CREATE INDEX ix_status ON orders(status);

SELECT *
FROM orders
WHERE region = 'EAST'
  AND status = 'OPEN';
Operator Meaning Typical predicate
IXAND Intersect RID streams Predicates combined by AND
IXOR Union RID streams Predicates combined by OR

Instructor note

When delegates see IXAND/IXOR in a plan, it’s a strong cue to evaluate index design (single composite index vs multiple simple indexes) and predicate selectivity assumptions.

5) Distribution Statistics: num_freqvalues & num_quantiles

Db2 uses statistics to estimate filter factors (selectivity). When data is skewed, uniform assumptions fail. Distribution statistics improve accuracy: N most frequent values and M quantiles. :contentReference[oaicite:2]{index=2}

Statistic Best for Helps with Example predicate
NUM_FREQVALUES (N most frequent values) Equality Value skew (hot values) status = 'ACTIVE'
NUM_QUANTILES (M quantiles / histogram) Ranges Interval skew (dense ranges) salary BETWEEN x AND y
SQL · Set database defaults
-- Database-level defaults for distribution statistics
UPDATE DB CFG USING num_freqvalues 20;
UPDATE DB CFG USING num_quantiles 50;

Production tuning caution

Higher values increase RUNSTATS cost and catalog footprint. Use higher settings selectively on high-impact columns (join keys, filter columns, partitioning keys).

SQL · Per-column distribution (RUNSTATS)
RUNSTATS ON TABLE employee
WITH DISTRIBUTION
ON COLUMNS (
  status NUM_FREQVALUES 50,
  salary NUM_QUANTILES 100
)
AND INDEXES ALL;

Instructor “why this matters” line

Accurate filter factors prevent the optimizer from choosing a TBSCAN when an index would be optimal — or choosing an index path that explodes into random I/O due to bad selectivity estimates.

6) Column Group Statistics (Correlation)

When predicates reference correlated columns, independence assumptions can cause severe misestimation. Column group statistics capture joint cardinality so the optimizer estimates selectivity correctly. :contentReference[oaicite:3]{index=3}

Classic correlation example

Not all combinations exist in real data (e.g., only certain models for a manufacturer). Without column group stats, Db2 may assume every model can pair with every manufacturer.

SQL · Collect column group statistics
RUNSTATS ON TABLE carmodels
ON COLUMNS ((manufacturer, model))
WITH DISTRIBUTION
AND INDEXES ALL;

Instructor tip

Teach delegates to find correlation candidates by scanning top queries: multi-predicate WHERE clauses and join conditions across the same table are prime candidates for column groups.

Signal Example Action
Frequent multi-column filters WHERE A=? AND B=? Create column group stats
Join + local predicate together JOIN ... ON K + WHERE status=? Consider stats view / column group
Plan instability Flips TBSCAN ↔ IXSCAN Improve distribution + correlation stats

7) Production Runbook (SOP) – What You Teach Delegates to Do

This is a practical tuning SOP you can give learners as “how a real DBA works”. It aligns with course emphasis: maintenance (RUNSTATS/REORG), explain, and indexing choices. :contentReference[oaicite:4]{index=4}

  1. Confirm stats freshness: RUNSTATS age, table volatility, and whether distribution/correlation stats exist.
  2. Explain the statement: capture and render with db2exfmt; focus on optimized statement + operators + cardinalities.
  3. Validate predicate stages: identify residual predicates and non-sargable expressions.
  4. Inspect index suitability: leading keys, clustering, and whether multi-index access is being used (IXAND/IXOR).
  5. Decide: stats vs index vs REORG:
    • Wrong selectivity → improve distribution/correlation stats
    • No efficient access path → adjust indexing
    • Good plan but high I/O → check clustering / overflow → REORG
  6. Re-test & compare: measure with consistent inputs; document plan changes and reasons.

Common failure mode

Index added, but clustering is terrible — so plan looks good on paper but runtime I/O is terrible. Always validate cluster ratio and physical drift before “blaming SQL”.

8) Appendix – Copy/Paste Command Library

CLP · Explain + db2exfmt quick-run
-- EXPLAIN a query
EXPLAIN PLAN FOR
SELECT * FROM <schema>.<tab> WHERE <predicate>;

-- Render latest explain
db2exfmt -d <dbname> -1 -o plan.txt
CLP · REORG (template)
-- Table REORG (example)
db2 "REORG TABLE <schema>.<tab> INPLACE ALLOW READ ACCESS"

-- Index REORG (example)
db2 "REORG INDEXES ALL FOR TABLE <schema>.<tab> ALLOW READ ACCESS"
SQL · RUNSTATS profile pattern
-- Register a statistics profile (doesn't collect)
RUNSTATS ON TABLE <schema>.<tab>
  WITH DISTRIBUTION
  AND SAMPLED DETAILED INDEXES ALL
  SET PROFILE ONLY;

-- Later: run using stored profile
RUNSTATS ON TABLE <schema>.<tab> USE PROFILE;
SQL · SYSSTAT quick checks
-- Tables
SELECT tabschema, tabname, card, npages, fpages, overflow
FROM sysstat.tables
WHERE tabschema='<SCHEMA>' AND tabname='<TABNAME>';

-- Indexes
SELECT indschema, indname, firstkeycard, fullkeycard, cluster_ratio
FROM sysstat.indexes
WHERE tabschema='<SCHEMA>' AND tabname='<TABNAME>';