2026年3月13日金曜日

SQL Server TempDB の仕組みと最適化|一時オブジェクト・ソート・バージョン管理の理解

TempDBとは何か|SQL Serverの内部処理を支える重要データベース

SQL Server のパフォーマンスを考えるうえで、見落とされがちな要素が「TempDB(テンポラリデータベース)」です。
一時テーブルやテーブル変数、ソート処理、ハッシュ集計、スナップショット分離など、TempDB はほとんどすべてのデータベース処理に関与しています。
しかし、この TempDB はサーバー全体で共有される単一のシステムデータベースであり、設計や運用を誤ると「PAGELATCH待機」や「ディスクI/O過多」などのボトルネックを招きます。
本記事では、TempDB の役割と内部構造をわかりやすく整理し、実務で役立つ最適化・チューニングの要点を解説します。

目次

TempDBとは何か

TempDBの役割と特徴

TempDB(テンポラリデータベース)は、SQL Server が内部処理で利用する一時的な作業領域です。
他のデータベースと異なり、サーバー再起動のたびに自動的に初期化されるという特徴を持っています。
TempDB では次のようなデータが扱われます。

  • 一時テーブル(#TempTable、##TempTable)
  • テーブル変数(@TableVar)
  • ソート・ハッシュ・集計などの一時領域(ワークテーブル/ワークファイル)
  • カーソルやスプール操作で生成されるワークテーブル
  • スナップショット分離等で使われるバージョンストア

これらの処理を効率よく裁くことが、SQL Server 全体のスループットを左右します。
そのため TempDB は「補助領域」ではなく、実務的にはシステム全体の性能を支える中核データベースといえます。

他のデータベースとの違い

TempDB は、一般的なユーザーデータベースと次の点で大きく異なります。

比較項目 一般的なデータベース TempDB
永続性 データを永続的に保持 サーバー再起動時に初期化
ログモデル 完全復旧/一括ログ復旧などを選択可能 単純復旧モデル(ログ最小化)
作成数 複数作成可能 インスタンスあたり1つのみ
用途 業務データ格納やアプリケーション用DB 内部処理・一時領域を全体で共有

このように、TempDB は「再起動で初期化」「共有リソース」「ログ最小化」という特殊な性質を持ちます。
そのため、他のデータベースと同じ設計方針を適用すると、性能劣化やリソース競合を引き起こす要因となるのです。

TempDBの内部構造

ファイル構成と配置(MDF・NDF・LDF)

TempDB は、他のデータベースと同様にプライマリデータファイル(MDF)セカンダリデータファイル(NDF)、およびトランザクションログファイル(LDF)で構成されます。
ただし、TempDB はログが最小化される「単純復旧モデル」で動作するため、LDF は最小限の管理用途に留まります。
データ格納の主役となるのは MDF および複数の NDF ファイルであり、これらを適切に分割・配置することで I/O 負荷を分散できます。

特に大規模環境では、CPUコア数に応じて複数の NDF ファイルを用意し、同一サイズで分散配置することが推奨されます。
たとえば 8 コア環境では、8 つの NDF ファイルを同一サイズで配置するのが一般的です。これにより PAGELATCH 競合が軽減し、TempDB のスループットが安定します。

ページ構造と PFS/GAM/SGAM

TempDB も通常のデータベースと同様、内部的には 8KB 単位のデータページで管理されています。
SQL Server ではページ割り当てを追跡するために、以下のシステムページが利用されます。

  • PFS(Page Free Space):各ページの空き領域を管理
  • GAM(Global Allocation Map):エクステント(8ページ単位)の割り当て状況を管理
  • SGAM(Shared Global Allocation Map):共有可能なエクステントの情報を管理

これらの管理ページは頻繁に更新されるため、特に同一ファイル内にアクセスが集中するとPAGELATCH 待機が発生しやすくなります。
そのため、PFS や GAM ページを分散させるためのファイル分割設計が TempDB の性能を左右します。

バージョンストアの仕組み

TempDB には、スナップショット分離やオンラインインデックス再構築などで利用されるバージョンストア(Version Store)が存在します。
これは、更新中の行データを一時的に保持して、他トランザクションからの読み取り一貫性を確保する仕組みです。
たとえば、READ COMMITTED SNAPSHOT モードでは、更新前の行バージョンが TempDB 内に保存されます。

バージョンストアが肥大化すると、TempDB のディスク使用量が急増し、I/O 負荷が上がります。
このため、長時間トランザクション読み取り一貫性を多用するアプリケーションでは、TempDB の監視とメンテナンスが重要です。

TempDBが使われる主なシナリオ

一時テーブル・テーブル変数の格納

開発や運用でよく使われる一時テーブル(#TempTable)テーブル変数(@TableVar)は、いずれも TempDB に物理的に格納されます。
一時テーブルは明示的に DROP するかセッション終了時に自動削除されますが、その間 TempDB 内では実際にデータがページとして確保されています。
テーブル変数も内部的には同様に TempDB を利用するため、大量データを扱う場合はメモリ上ではなくディスク I/O に影響を与える点に注意が必要です。

ソート・ハッシュ・集計などの一時領域

ORDER BY、GROUP BY、HASH JOIN などの処理では、SQL Server がメモリを超えたデータ量を扱う際に、一時的なワークテーブルワークファイルを TempDB に作成します。
これらはメモリ不足や統計情報の偏りによって発生しやすく、頻発するとディスクI/O負荷の主因となります。
実行計画上では「Spool」「Worktable」「Workfile」などのオペレーターとして確認できます。

スナップショット分離やバージョン管理

データの一貫性を保つためのスナップショット分離(READ COMMITTED SNAPSHOTSNAPSHOT ISOLATION)でも、TempDB がバージョン情報の格納先となります。
更新トランザクションが発生するたびに、変更前のデータがバージョンストアに保持され、読み取り側はそこから過去のデータを参照します。
これにより読み取りブロッキングを防げますが、同時に TempDB の容量使用率が上昇するため、バージョンストアの監視が不可欠です。

TempDBのボトルネックと原因

頻繁なディスクI/Oと競合

TempDB は多くの処理で共有されるため、ディスク I/O が集中しやすい傾向があります。
特に、ソート・ハッシュ結合・グループ化・一時テーブル生成などが頻発する環境では、ディスクのスループットがボトルネックとなります。
ストレージが単一ディスクや低速な HDD で構成されている場合、TempDB の応答遅延が全体性能に直結します。

対策:TempDB 用の専用ドライブを確保し、SSD などの高速ストレージを使用することが推奨されます。
また、読み取りと書き込みが混在する負荷を分散させるために、複数ファイルを別々の物理ディスクに配置するのも有効です。

PAGELATCH待機(リソース競合)

PAGELATCH 待機は、TempDB のページ管理構造(PFS、GAM、SGAM)にアクセスが集中した際に発生します。
特に同一ファイル内の先頭領域に複数スレッドが同時アクセスする場合、内部的なロック競合が発生し、処理が待機状態となります。

対策:CPU コア数に合わせて複数のデータファイル(NDF)を作成し、同サイズ・同ドライブ上に分散配置することが基本です。
Microsoft 公式ガイドラインでは、論理コア数に応じて最大 8 ファイル程度まで分割することが推奨されています。
必要に応じて段階的に拡張し、PAGELATCH 競合が解消されるまで最適数を調整します。

ファイルサイズと自動拡張の影響

TempDB のファイルが小さすぎると、頻繁な自動拡張(Auto Growth)が発生し、そのたびにパフォーマンスが低下します。
拡張操作はシリアルに処理されるため、複数スレッドが同時に拡張要求を行うとブロッキングが発生します。

対策:運用開始前に十分な初期サイズを設定し、自動拡張の頻度を最小限に抑えることが重要です。
初期構築時に 1 ファイルあたり数 GB 単位で設定し、拡張単位(例:512MB)も固定値に設定しておくと安定します。

TempDBの最適化・チューニング方法

ファイル分割と均等配置

TempDB の性能改善でもっとも効果が大きいのが、データファイルの分割です。
複数の NDF ファイルを用意し、CPU 論理コア数に合わせて均等サイズで配置することで、ページ割り当て負荷を分散できます。
全ファイルの初期サイズを同一に設定し、同じドライブ上に配置することがポイントです。


ALTER DATABASE tempdb 
ADD FILE (NAME = tempdev2, FILENAME = 'E:\MSSQL\DATA\tempdb_mdf2.ndf', SIZE = 2048MB, FILEGROWTH = 512MB);

オートグロース設定の最適化

自動拡張(Auto Growth)は緊急的な拡張として便利ですが、過度に依存すると断続的な遅延を引き起こします。
すべてのファイルに対して、固定サイズ(例:512MB)で拡張するよう設定し、パーセンテージ指定は避けるのが望ましいです。


ALTER DATABASE tempdb 
MODIFY FILE (NAME = tempdev, FILEGROWTH = 512MB);

トレースフラグと初期サイズ調整

SQL Server には TempDB の起動時初期化を最適化するトレースフラグが用意されています。
たとえば、TF1117 および TF1118 は、ファイル拡張とページ割り当てを均等化するための設定です(SQL Server 2016 以降は既定動作化)。

また、初期サイズを適切に設定することで、起動直後から安定したパフォーマンスを維持できます。


ALTER DATABASE tempdb 
MODIFY FILE (NAME = tempdev, SIZE = 4096MB);

バージョンストア肥大化の防止策

スナップショット分離モードや長時間トランザクションによって、TempDB のバージョンストアが肥大化することがあります。
これを防ぐために、長時間実行トランザクションの監視と、不要なスナップショット分離の抑制が重要です。

以下のクエリで、バージョンストア使用量を監視できます。


SELECT SUM(version_store_reserved_page_count) * 8 / 1024 AS VersionStoreMB
FROM sys.dm_db_file_space_usage;

異常な肥大化が見られる場合は、アプリケーション側の分離レベル設定やトランザクション設計の見直しを行いましょう。

まとめ

TempDB最適化の要点整理

  • TempDB はサーバー全体で共有される重要なリソースである
  • ファイル分割と均等配置により PAGELATCH 競合を防止
  • Auto Growth 頻発を防ぐため初期サイズを十分に確保
  • バージョンストアの肥大化は定期的に監視
  • 高速ディスクと専用ストレージの導入が有効

実務での推奨設定例

以下は一般的な中規模環境での推奨設定例です。


-- TempDB ファイル分割とサイズ調整例
ALTER DATABASE tempdb 
MODIFY FILE (NAME = tempdev, SIZE = 4096MB, FILEGROWTH = 512MB);
ALTER DATABASE tempdb 
ADD FILE (NAME = tempdev2, SIZE = 4096MB, FILEGROWTH = 512MB);
ALTER DATABASE tempdb 
ADD FILE (NAME = tempdev3, SIZE = 4096MB, FILEGROWTH = 512MB);
ALTER DATABASE tempdb 
ADD FILE (NAME = tempdev4, SIZE = 4096MB, FILEGROWTH = 512MB);

これらを適切に設定し、定期的にバージョンストアやディスクI/Oの状態をモニタリングすることで、TempDB のボトルネックを未然に防ぐことができます。

SQL Server学習シリーズ
◀ 【第1回】テンポラリテーブルとテーブル変数の違い
【第8章 第1回】メモリとバッファプールの仕組み ▶
目次へ

参考リンク

SQL Server 解説用イメージ

0 件のコメント:

コメントを投稿