SQL Server統計情報とは?役割・更新方法・実行プランとの関係を初心者向けに解説

SQL Server

SQL Server を使っていていると、SQL が遅くなることがありますが、こうしたパフォーマンス問題を調査するうえで重要なのが、統計情報(Statistics)です。
SQL Server統計情報の役割や仕組み、更新方法を初心者向けに解説します。AUTO_UPDATE_STATISTICSやUPDATE STATISTICS、実行プランとの関係も図解イメージでわかりやすく説明。

SQL Server の統計情報とは?

統計情報(Statistics)とは、「テーブル内のデータ分布を SQL Server に伝える情報」です。
SQL Server は統計情報を利用して、データ件数、値の偏り、重複率などを把握し、最適な実行方法を決定します。

SQL Server の統計情報

統計情報活用例

統計情報は「テーブルの中にどんなデータが、どれくらい入っているか」を把握するための情報です。
SQL Server は SQL を実行する前に、どう実行すると一番速いかを考えますが、このときに使われるのが統計情報です。

例えば「社員」テーブルに大量のデータがあるとします。
ここから「住居の都道府県」の社員を取得したい場合、「住居の都道府県」=’東京都’のデータは少ないと分かっていれば、インデックスを使って必要な行だけ探す(Index Seek)という高速な方法を選べます。逆に、ほとんどのデータが ‘東京都’なら、全件読み込んだほうが速いです。

統計情報

SQL Serverは、どの値がどれくらい存在するかをヒストグラム(データ分布表)で保持しています。
なお、統計情報サイズを大きくしすぎないために、最大200ステップまでとしています。

統計情報のヒストグラム

統計情報が古いとSQL が遅くなる

統計情報が古いことが原因で、SQLが遅くなることは実務ではかなり頻出します。

先ほどの例で、昔は’東京都’のデータが多かったのに、現在は’東京都’以外のデータが増えていたとします。
そうすると、SQL Server は、誤った方法でデータを検索してしまいます。

統計情報が古いことで起きる問題は次の通りです。

  • 不適切な Index Seek
  • 無駄なループ JOIN
  • 過剰なメモリ使用

SQL Serverは統計情報を自動更新する設定がありますが、SQL Serverはある程度データ変更されたら統計情報を更新するので、大量データの追加・更新・削除を実施した場合、自動更新が有効になっていても統計情報が更新されないことがあります。

統計情報が古くなる

統計情報の設定・内容確認手順

統計情報の自動更新設定確認手順

次のSQLは、データベース 名「DB01」 の統計情報自動更新設定を確認するためのものです。

SELECT name, is_auto_update_stats_on, is_auto_update_stats_async_on
FROM sys.databases
WHERE name = 'DB01';

「is_auto_update_stats_on」列が1の場合は、自動更新が有効です。
「is_auto_update_stats_async_on」が1の場合は、非同期自動更新が有効です。

「is_auto_update_stats_async_on」(非同期自動更新)が無効の場合、統計更新をクエリと同期して待つので、クエリの待機が発生する可能性があります。
その代わり、最新統計で統計情報が更新されます。

統計情報の確認

次のSQLでどのテーブルの統計情報がいつ更新されていて、どれくらい古くなっているかを確認できます。

SELECT
    t.name AS table_name,
    s.name AS stats_name,
    sp.last_updated,
    sp.rows,
    sp.rows_sampled,
    sp.modification_counter
FROM sys.stats s
JOIN sys.tables t
    ON s.object_id = t.object_id
CROSS APPLY sys.dm_db_stats_properties(s.object_id, s.stats_id) sp
WHERE sp.last_updated IS NOT NULL
ORDER BY sp.last_updated desc;
説明
table_name対象テーブル名
stats_name統計情報の名前(インデックス or 手動統計)
last_updated最後に統計が更新された日時
rows統計対象の行数
rows_sampled統計作成時にサンプルされた行数
modification_counter統計作成後に変更された行数

統計情報の手動更新手順

SQL Serverの統計情報は自動更新設定されていても、統計情報が古いままとなることがあります。
その場合、統計情報を手動で更新することもできます。

統計情報の手動更新は、基本的にオンライン中(システム稼働中)に実行して良いですが、負荷がかかるので、可能であればオフライン時か利用者が少ない時間帯に実施を推奨します。

テーブルやインデックス単位で統計情報を更新する手順

テーブルやインデックス単位で、特定の統計情報を指定して更新する場合は以下のコマンドを実行します。

UPDATE STATISTICS dbo.EMP;

まとめて統計情報を更新する手順

データベース内の全ユーザー定義テーブルの統計をまとめて更新する場合は以下のコマンドを実行します。

EXEC sp_updatestats;

実行プランとの関係

SQL Serverでは、SQLを実行する前に「どのような手順でデータを取得するか」をクエリオプティマイザ(Optimizer)が判断します。
この処理手順を「実行プラン(Execution Plan)」と呼びます。

オプティマイザは、できるだけ高速にSQLを実行するために、統計情報の推定行数を利用してデータ件数や値の分布を推定しています。

統計情報と実行プラン

SQL Serverのクエリオプティマイザは、統計情報を利用してデータ件数を推定し、最適と思われる実行プランを選択します。
統計情報が不正確な場合、実際のデータ量に合わない実行プランが選択されることがあります。

まとめ

  • 統計情報(Statistics)は、SQL Serverがデータ件数や分布を把握するための情報
  • SQL Serverのクエリオプティマイザは、統計情報を利用して実行プランを決定している
  • 統計情報が古い場合、推定行数がずれ、不適切な実行プランが選択されることがある
  • 不適切な実行プランにより、Index Scan増加やSQL性能低下が発生する場合がある
  • SQL ServerにはAUTO_UPDATE_STATISTICSによる自動更新機能がある
  • 大量データ更新後などでは、必要に応じて手動で統計情報を更新することが重要
  • 統計情報は UPDATE STATISTICS や sp_updatestats で更新できる
  • DBCC SHOW_STATISTICS や sys.stats を利用すると統計情報を確認できる
  • 実行プランを理解すると、統計情報がSQL性能に与える影響をより深く理解できる
  • SQL Serverのパフォーマンス改善では、統計情報・実行プラン・インデックスをあわせて確認することが重要

コメント

タイトルとURLをコピーしました