DB2 8 min read

Db2のRUNSTATSとは ― コマンドの書き方と、統計が更新されたかの確かめ方

RUNSTATS は、表と索引の統計(行数、ページ数、列の値の偏りなど)を集めてシステムカタログに書き込む Db2 のコマンドです。オプティマイザーはこの統計を見て、索引を使うか、どの順で結合するかを決めます。統計が実際のデータとずれていると、遅いアクセスパスが選ばれます。この記事の出力は Db2 12.1.4 で採りました。

まず見る(結論)

  • 基本形: db2 "RUNSTATS ON TABLE スキーマ.表 WITH DISTRIBUTION AND INDEXES ALL"
  • 流れたかは SYSCAT.TABLES の STATS_TIME で見る。CARD が -1 なら一度も集めていない
  • 大きな表は TABLESAMPLE BERNOULLI(10) で抜き取って集められる。行数は推定値になる
  • 大量の投入・削除や REORG の後に流す(REORG の記事)

コマンドの書き方

やりたいこと コマンド
表と全索引(通常はこれ) RUNSTATS ON TABLE スキーマ.表 WITH DISTRIBUTION AND INDEXES ALL
表だけ RUNSTATS ON TABLE スキーマ.表
行を10%抜き取る ... AND INDEXES ALL TABLESAMPLE BERNOULLI(10)
ページを10%抜き取る ... TABLESAMPLE SYSTEM(10)
SQL から実行する CALL SYSPROC.ADMIN_CMD('RUNSTATS ON TABLE スキーマ.表 AND INDEXES ALL')

WITH DISTRIBUTION を付けると、列ごとに「どの値が何行あるか」(頻度統計)と値の分布(分位統計)も集めます。区分コードのように特定の値に行が偏る列があるなら付けます。

統計が更新されたかを確かめる

5万行を入れた直後の表です。

SELECT TABNAME, CARD, NPAGES, FPAGES, OVERFLOW, STATS_TIME
  FROM SYSCAT.TABLES WHERE TABNAME = 'FSV_REORG';

TABNAME      CARD   NPAGES   FPAGES   OVERFLOW STATS_TIME
------------ ------ -------- -------- -------- --------------------------
FSV_REORG        -1       -1       -1       -1 -                            ← 実行前
FSV_REORG     50000      747      747        0 2026-10-24-16.30.05.625221   ← 実行後

索引は SYSCAT.INDEXES(NLEAF・NLEVELS・CLUSTERRATIO・STATS_TIME)、頻度統計は SYSCAT.COLDIST に入ります。区分列 KBN を5行に1行ずつ 'A'・'B'、残りを 'C' にした表では、WITH DISTRIBUTION を付けて流すと COLDIST にこう記録されました。

SELECT COLNAME, TYPE, SEQNO, COLVALUE, VALCOUNT
  FROM SYSCAT.COLDIST
 WHERE TABNAME = 'FSV_REORG' AND COLNAME = 'KBN' AND TYPE = 'F' AND VALCOUNT > 0;

COLNAME  TYPE SEQNO  COLVALUE   VALCOUNT
-------- ---- ------ ---------- --------
KBN      F         1 'C'           30000
KBN      F         2 'A'           10000
KBN      F         3 'B'           10000

SQL が遅くなったときに最初に見るのは STATS_TIME です。大量に行を入れた日より前の日時なら、統計は投入前のデータのままです。

サンプリングすると行数は推定値になる

同じ5万行の表に TABLESAMPLE BERNOULLI(10) と TABLESAMPLE SYSTEM(10) を続けて流したところ、CARD は 50049 になりました。件数を正確に知りたいときは SELECT COUNT(*) を使います。

BERNOULLI は全ページを読んで行単位で抜き取ります。SYSTEM はページ単位で抜き取るので読む量が少なく速い一方、データの並びに偏りがあると統計も偏ります。

エラーになる場合

メッセージ 原因
SQL2306N The table or index "DB2INST1.NO_SUCH_TABLE" does not exist. 表名かスキーマの誤り。スキーマを省いて別ユーザーで接続している場合も出る
SQL20288N ... Object type: "View". Reason code: "1". ビューを指定した。統計を集められるのは表(と統計ビュー)

自動 RUNSTATS

DB CFG の AUTO_RUNSTATS が ON なら、Db2 が必要と判断した表に RUNSTATS を流します。

$ db2 get db cfg for sample | grep -i auto_
 Automatic maintenance                      (AUTO_MAINT) = ON
   Automatic table maintenance          (AUTO_TBL_MAINT) = ON
     Automatic runstats                  (AUTO_RUNSTATS) = ON
       Real-time statistics            (AUTO_STMT_STATS) = ON
     Automatic reorganization               (AUTO_REORG) = OFF

自動 RUNSTATS はいつ流れるかを選べません。大量投入の直後に流れるとは限らないので、バッチで大量に入れた後は手で流すほうが確実です。

RUNSTATS を流すタイミング(実機ログつきの詳解)

REORGCHK で実行要否を測る手順、自動 RUNSTATS が業務のピークに流れて実行計画が変わる問題、AUTO_REORG の性質は、Zenn のフル記事にまとめています。

▶ Zennで続きを読む(無料)

Db2の「とりあえず週次で全REORG」をやめる ― REORGCHKでいつやるかを判断する


実機ログつきの詳解を読む →

関連: Db2のREORGとは

この記事で解決しなかったときは

Db2 の技術的な質問を無料で受け付けています。エラーメッセージの全文と Db2 のバージョンを添えて送ってください。回答はメールで返します。

Db2 の相談を送る →

「とりあえず週次で全テーブルREORG」がなぜ問題を招くのか――“なぜ実行するのか”を自分で判断できるようになるための考え方を、本書 第10章「RUNSTATS・REORGを意図して制御する」で詳説しています。

現場で引ける Db2 の教科書

現場で引ける!Db2実践エンジニア・バイブル

Db2はRDBMS市場でシェア数%。情報が少なく、頼れるのは膨大な公式マニュアルだけ―― そんな現状を変えたくて、「なぜこの値にするのか」「この障害のとき次に何を見るのか」という、マニュアルに載っていない現場の文脈を1冊にまとめました。書いてあることはすべて実際の現場で経験したことです。

アーキテクチャ/構成パラメーター選定/セキュリティ/バックアップ・リカバリ/HADR/pureScale/日常点検の自動化/メモリ・ロック競合/SQLチューニング/RUNSTATS・REORG/MON_GET監視/現場の難題集 ―― 全12章+運用シェルスクリプト集。

Zennで読む →