NANAシステム開発 株式会社
STAFF BLOG

【SQL Server】TEMPDB のデータファイルが巨大で困ったけど…調べたら “むしろ適正”?

2026.02.24

こんにちは。NANAシステム開発SYです。今回は技術ネタです。

 

■最適サイズを探っていくための記録

SQL Server を運用していると、tempdb のサイズが気づいたらとんでもなく大きくなっていた――という経験は多くの管理者が一度は通る道ではないでしょうか。

先日、まさに自分の環境で同じ状況に遭遇し、「これはさすがに大きすぎるのでは?」と思って調査を始めました。

ところが色々調べていくうちに、
「あれ?これ Microsoft の推奨サイズ(=適正サイズ)に近いのでは…?」
という結論に近づいていきました。

今回はその気づきと、実際に tempdb がどれだけ使われているかを記録し、最適サイズを導き出すまでのプロセスをまとめます。

 

■ そもそも tempdb は “大きくなるもの”

tempdb は SQL Server の作業領域として、次のような処理に使われるようです。

・ORDER BY / GROUP BY など大規模ソート

・ハッシュ結合・ハッシュ集計

・一時テーブル・テーブル変数

・Snapshot Isolation / RCSI のバージョンストア

・インデックス再構築(ONLINE)

このため、上記をガンガン行うアプリケーションほど tempdb はよく伸びます。

しかも、SQL Server はサービス再起動のたびに tempdb を初期サイズにリセットするため、
初期サイズが小さいとピーク負荷時に一気に巨大化してしまうことがあります。

なので、「ファイルを小さくしても、また必要に応じて大きくなった」と感じることがあります。

縮小コマンドもあるのですが、縮小しても、負荷が来れば SQL Server が自動で再拡張します。逆に言えば、縮小を繰り返すと
「縮小 → 拡張 → 縮小 → 拡張」
という悪循環が起き、パフォーマンスを落としていたように思います。

 

■ Microsoft の推奨サイズに “落ち着いていた” という気づき

tempdb の適正サイズは
「CPU コア数 ×(8GB 〜 16GB / ファイル)」
というのが Microsoft の基本推奨です。

例えば CPU 8コアなら:

・ファイル数:8個

・1ファイル初期サイズ:8GB

・合計:64GB

巨大化したと悩んでいた環境でふと確認すると、まさに この推奨レンジに収まっていた のです。

「巨大化した!」と焦ったわりには、ただの最適化された姿だったわけです。

 

■ とはいえ、“実際にどれだけ使っているか” を知らないままでは判断できない

でも、いくら推奨値に収まっているとはいえ、本当に適正かどうかはワークロードを見て決めるべきです。

そこで、tempdb の使用量を 時系列でログに残す仕組み を作りました。

▼ TEMPDB の“実際の使用量”をログに残す T‑SQL

以下のようにログテーブルを作り、
SQL Server Agent で 1分ごとに実行することで
ピーク時の tempdb 消費量を詳細に把握できます。


▼ ログテーブル作成

CREATE TABLE dbo.TempdbUsageLog
(
LogId bigint IDENTITY(1,1) PRIMARY KEY,
LogTime datetime2(3) NOT NULL DEFAULT (SYSUTCDATETIME()),
TotalFileSizeMB decimal(18,2),
UsedMB decimal(18,2),
UserObjMB decimal(18,2),
InternalObjMB decimal(18,2),
VersionStoreMB decimal(18,2),
UnallocatedMB decimal(18,2),
DataFiles int
);

▼ 採取用プロシージャ

CREATE PROCEDURE dbo.Capture_Tempdb_Usage
AS
BEGIN
SET NOCOUNT ON;
;WITH Files AS
(
SELECT
name,
FileSizeMB = (size * 8.0) / 1024.0,
UsedMB = (FILEPROPERTY(name,‘SpaceUsed’) * 8.0) / 1024.0
FROM tempdb.sys.database_files
WHERE type = 0
),
SpaceUsage AS
(
SELECT
UserObjMB = SUM(user_object_reserved_page_count) * 8.0 / 1024.0,
InternalObjMB = SUM(internal_object_reserved_page_count) * 8.0 / 1024.0,
VersionStoreMB = SUM(version_store_reserved_page_count) * 8.0 / 1024.0,
UnallocatedMB = SUM(unallocated_extent_page_count) * 8.0 / 1024.0
FROM sys.dm_db_file_space_usage
)
INSERT dbo.TempdbUsageLog (TotalFileSizeMB, UsedMB, UserObjMB, InternalObjMB, VersionStoreMB, UnallocatedMB, DataFiles)
SELECT
(SELECT SUM(FileSizeMB) FROM Files),
(SELECT SUM(UsedMB) FROM Files),
su.UserObjMB,
su.InternalObjMB,
su.VersionStoreMB,
su.UnallocatedMB,
(SELECT COUNT(*) FROM Files)
FROM SpaceUsage su;
END

■ ログを取り始めてわかったこと

最初の数日記録をとってみて分かったのは、

・殆ど使っていない時間帯が多い

・逆に特定時間帯だけドカンと増える

ということ。

 

■ 今後の方針:実測しながら最適値に寄せていく

今後はログデータをもとに、

 ・ピーク使用量 + 20〜30% の余裕

 ・拡張が発生しない初期サイズ

 ・適切な autogrowth 設定(%ではなく固定MB)

これらを調整し、tempdb を“業務に最適化されたサイズ”へ整えていく予定です。

 

■ まとめ

・TEMPDB は負荷によって大きくなるのが普通

・縮小してもまた必要に応じて拡張する

・Microsoft 推奨サイズに近いことも多い

・本当に妥当かどうかは、実際の使用量をログに残して判断するべき

・ログを取るとワークロードの癖が見えてくる

・そこから初めて “最適サイズ” の議論ができる

tempdb の巨大化は “壊れている” のではなく、「あなたのワークロードを反映した姿」 であることが多いです。なので大事なのは、まずは実測から始めることだと感じました。

これが tempdb 最適化のスタート地点だと実感した出来事でした。些細な情報ですが、皆様のお役に立てれば幸いです。