
SQLServerのテーブルに対して突然アクセスが遅くなったってことないですか? 以下のことが原因の可能性が高いのでお試し下さい。
インデックスを再構築しても速くならない――そのとき疑うべきは統計情報(Statistics)です。統計はオプティマイザーが実行計画を作るための「地図と交通情報」。ここが古いと行数見積もりが外れ、間違ったルート(実行計画)を選びます。結果、スキャン多発・メモリスピル・ロック長期化→タイムアウトへ。本記事は、統計と実行計画の関係を直感的に説明し、これだけやればOKな運用コマンドを2つだけに絞って提示します。
目次
統計と実行計画の関係を“超直感”で
- 統計 = 地図+交通情報
テーブル列の「値の分布(ヒストグラム)」と「密度(選択度)」を持つのが統計。オプティマイザはこれを見て、どの道(インデックス)を通るか、どの順で結合するか、どれだけメモリを見積もるかを決めます。 - 実行計画 = カーナビのルート提案
地図(統計)が古いと、渋滞(データ偏り)を見落として遠回りや細道の連続を選んでしまう=スキャン・大量ルックアップ・重い結合。
具体イメージ(1分でわかる)
- 注文テーブル
Orders
が 1,000万行。 WHERE Status = 'Open'
の件数が、月初は 1%、月末は80%まで増えることがある。- 古い統計が「Open=1%」のままだと…
- 見積:少ないはず → インデックス・シーク+キー・ルックアップを選択
- 現実:実は80% → ルックアップだらけでI/O激増&ロック長期化
- 統計を更新すると…
- 見積:80%と正しく把握 → スキャン+ハッシュ結合など“広く一気に”処理する計画に切り替わり、時間短縮
ポイント:統計が古い=行数見積もりがズレる=実行計画の選択ミス。
インデックス再構築で速くならない時は、まず統計を疑うのが近道。
迷わない“これだけ運用”——コマンドは2つ
まずはこの2つだけをジョブ化すれば、多くの“突然遅い”を予防できます。
① 毎日:全体を軽くなでる(変更があった統計だけ更新)
EXEC sys.sp_updatestats;
- 効果:テーブル全体を重くしすぎず、統計をこまめに最新化
- 用途:日次の“基礎体力づくり”
② 週1(または大量更新の直後):重要テーブルを精密更新
UPDATE STATISTICS dbo.Orders WITH FULLSCAN;
- 効果:偏りが出やすい列でも行数見積もりの精度が高い
- 用途:業務で効くテーブル(注文・在庫・トランザクション系など)を数個だけ選んで実施
- 補足:列統計(
_WA_Sys...
)も含めて精密化したい場合、同じコマンドをテーブル名だけ指定すればOK(統計名は不要)。
どれが“重要テーブル”?
- 毎日大量に更新される/2) WHEREやJOINで頻出/3) 遅延が業務影響大――この3条件に当てはまるものから2〜5個だけ選ぶのが現実的です。
よくある勘違い(ここだけ押さえる)
- 「インデックス再構築=統計も全部新鮮」ではない
更新されるのはインデックス統計だけ。列統計は別途更新が必要。→ ②のコマンドでテーブル単位に更新すればケアできます。 - 自動統計ONでも大規模表は追いつかないことがある
日次の①に加え、週1の②で“要のテーブル”をしっかり精密化すると安定します。
運用ミニガイド(設定は最初に一度だけ)
すでに有効なことが多いですが、念のため確認。
ALTER DATABASE [YourDB] SET AUTO_CREATE_STATISTICS ON;
ALTER DATABASE [YourDB] SET AUTO_UPDATE_STATISTICS ON;
- これで必要な列統計の自動作成と自動更新が働きます。
- それでも足りないところを①+②で“上書き補強”するイメージです。
まとめ
- 統計は実行計画の“地図と交通情報”。古いと行数見積もりミス→間違った計画で遅くなる。
- 毎日:
sp_updatestats
/週1+大量更新後:UPDATE STATISTICS ... WITH FULLSCAN
――まずはこの2コマンド運用で十分強い。 - 重要テーブルを2〜5個に絞って精密更新するだけで、体感性能と安定性は大きく改善します。
コメント