次の方法で共有


tempdb データベース

適用対象: SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceMicrosoft Fabric SQL Database

この記事では、tempdb システム データベース、SQL Server、Azure SQL Database、または Azure SQL Managed Instance のデータベース エンジン インスタンスに接続されているすべてのユーザーが使用できるグローバル リソースについて説明します。

概要

tempdb システム データベースは、次のものを保持するグローバル リソースです。

  • ユーザーオブジェクト が明示的に作成される 場合。 それには次の内容を含みます。

    • グローバルまたはローカルの一時テーブルと、これらのテーブル上のインデックス
    • 一時ストアドプロシージャ
    • テーブル変数
    • テーブル値関数で返されるテーブル
    • カーソル

    ユーザー データベースで作成できるユーザー オブジェクトは、tempdbでも作成できますが、持続性を保証せずに作成され、データベース エンジン インスタンスの再起動時に削除されます。

  • データベース エンジンによって作成された "内部オブジェクト"。 それには次の内容を含みます。

    • スプール、カーソル、並べ替え、および一時的なラージ オブジェクト (LOB) 記憶域の中間結果を格納する作業テーブル。
    • ハッシュ結合操作またはハッシュ集計操作用の作業ファイル
    • インデックスの作成または再構築などの操作 (SORT_IN_TEMPDB が指定されている場合) や、GROUP BYORDER BYUNION などの特定のクエリにおける、並べ替えの中間結果。

    各内部オブジェクトでは、少なくとも 9 つのページが使用されます (IAM ページと 8 ページ分のエクステント)。 ページとエクステントの詳細については、「ページとエクステント」を参照してください。

  • バージョンには、が格納されます。これは、行のバージョン管理をサポートするデータ行を保持するデータ ページのコレクションです。 共通バージョン ストアとオンライン インデックス ビルド バージョン ストアの 2 種類があります。 バージョン ストアに保持される内容:

    • 行バージョン管理ベースの READ COMMITTED または SNAPSHOT 分離トランザクションを使用するデータベース内のデータ変更トランザクションによって生成される行バージョン。
    • オンライン インデックス操作、複数のアクティブな結果セット (MARS)、AFTER トリガーなどの機能に対するデータ変更トランザクションによって生成される行バージョン。

tempdb 内の操作は最小限に記録されます。 tempdb は、データベース エンジンが起動されるたびに再作成されるため、システムは常に空の tempdb データベースで起動します。 一時ストアド プロシージャとローカル一時テーブルは、一時ストアド プロシージャを作成したセッションが切断されると自動的に削除されます。

tempdb はデータベースエンジンのアップタイム期間から別の期間にかけて保存すべきものは一切ありません。 tempdb では、バックアップおよび復元の操作は実行できません。

SQL Server での tempdb の物理プロパティ

次の表は、SQL Server での tempdb のデータ ファイルとログ ファイルの初期構成値の一覧です。 値は、model データベースの既定値に基づいています。 これらのファイルのサイズは、 SQL Server のエディションによって多少異なる場合があります。

ファイル 論理名 現物名 初期サイズ ファイル拡張
プライマリ データ tempdev tempdb.mdf 8 MB ディスクがいっぱいになるまで 64 MB ずつ自動拡張
セカンダリ データ ファイル* temp# tempdb_mssql_#.ndf 8 MB ディスクがいっぱいになるまで 64 MB ずつ自動拡張
ログ templog templog.ldf 8 MB 最大 2 TB まで 64 MB ずつ自動拡張

すべての tempdb データ ファイルは、常に同じ初期サイズと拡張パラメーターを持つ必要があります。

tempdb データ ファイルの数

データベース エンジンのバージョン、その構成、ワークロードによっては、tempdb 割り当ての競合を軽減するために複数のデータ ファイルが必要になる場合があります。

推奨されるデータ ファイルの合計数は、マシン上の論理プロセッサの数によって異なります。 一般的なガイダンス:

  • 論理プロセッサの数が 8 以下の場合は、同じ数のデータ ファイルを使用します。
  • 論理プロセッサの数が 8 より多い場合は、8 つのデータ ファイルが使用されます。
  • tempdb 割り当ての競合が引き続き発生する場合は、競合が許容できるレベルに減少するか、ワークロードに変更を加えるまで、データ ファイルの数を 4 の倍数で増やします。

詳細については、「推奨事項」を参照して、SQL Server tempdb データベースでの割り当ての競合を減らします。

tempdbの現在のサイズと増加のパラメーターを確認するには、tempdbsys.database_files カタログ ビューを使用します。

SQL Server の tempdb のデータ ファイルとログ ファイルの移動

tempdb のデータ ファイルとログ ファイルを移動するには、「システム データベースの移動」を参照してください。

SQL Server での tempdb のデータベース オプション

tempdb データベースの各データベース オプションの既定値とそのオプションを変更できるかどうかを次の表に示します。 これらのオプションの現在の設定を表示するには、 sys.databases カタログ ビューを使用します。

データベース オプション 規定値 変更可否
ACCELERATED_DATABASE_RECOVERY OFF いいえ
ALLOW_SNAPSHOT_ISOLATION OFF はい
ANSI_NULL_DEFAULT OFF はい
ANSI_NULLS OFF はい
ANSI_PADDING OFF はい
ANSI_WARNINGS OFF はい
ARITHABORT OFF はい
AUTO_CLOSE OFF いいえ
AUTO_CREATE_STATISTICS ON はい
AUTO_SHRINK OFF いいえ
AUTO_UPDATE_STATISTICS ON はい
AUTO_UPDATE_STATISTICS_ASYNC OFF はい
AUTOMATIC_TUNING (FORCE_LAST_GOOD_PLAN) OFF いいえ
CHANGE_TRACKING OFF いいえ
COMPATIBILITY_LEVEL データベース エンジンのバージョンによって異なります。

詳細については、ALTER DATABASE (Transact-SQL) 互換性レベル を参照してください。
はい
CONCAT_NULL_YIELDS_NULL OFF はい
CONTAINMENT NONE いいえ
CURSOR_CLOSE_ON_COMMIT OFF はい
CURSOR_DEFAULT GLOBAL はい
データベースの状態 ONLINE いいえ
データベースの更新 READ_WRITE いいえ
データベース ユーザー アクセス MULTI_USER いいえ
DATE_CORRELATION_OPTIMIZATION OFF はい
DB_CHAINING ON いいえ
DELAYED_DURABILITY DISABLED

このオプションに関係なく、遅延持続性は常に tempdbで有効です。
はい
ENCRYPTION OFF いいえ
MIXED_PAGE_ALLOCATION OFF いいえ
NUMERIC_ROUNDABORT OFF はい
PAGE_VERIFY SQL Server の新規インストールの CHECKSUM

既存の PAGE_VERIFY 値は、SQL Server のインスタンスが所定の場所にアップグレードされるときに保持される場合があります。
はい
PARAMETERIZATION SIMPLE はい
QUOTED_IDENTIFIER OFF はい
READ_COMMITTED_SNAPSHOT OFF いいえ
RECOVERY SIMPLE いいえ
RECURSIVE_TRIGGERS OFF はい
サービスブローカー ENABLE_BROKER はい
TARGET_RECOVERY_TIME 60 はい
TEMPORAL_HISTORY_RETENTION ON はい
TRUSTWORTHY OFF いいえ

これらのデータベース オプションの説明は、「ALTER DATABASE の SET オプション (Transact-SQL)」を参照してください。

Azure SQL Database の tempdb

Azure SQL Database では、tempdb の動作と構成の一部の側面が SQL Server とは異なります。

単一データベースの場合、論理サーバー上の各データベースには独自の tempdbがあります。 エラスティック プールでは、tempdb は同じプール内のすべてのデータベースの共有リソースですが、1 つのデータベースによって作成された一時オブジェクトは、同じエラスティック プール内の他のデータベースには表示されません。

カタログ ビューや動的管理ビュー (DMV) など、tempdb内のオブジェクトには、tempdb データベースへのデータベース間参照を介してアクセスできます。 たとえば、sys.database_files ビューに対してクエリを実行できます。

SELECT file_id,
       type_desc,
       name,
       size,
       max_size,
       growth
FROM tempdb.sys.database_files;

Azure SQL Database のグローバル一時テーブルは、データベースのスコープに制限されています。 詳細については、Azure SQL Database のデータベース スコープのグローバル一時テーブルを参照してください。

Azure SQL Database での tempdb のサイズの詳細については、次を確認してください。

SQL Managed Instance での tempdb

Azure SQL Managed Instance では、tempdb 動作と既定の構成の一部が SQL Server とは異なります。

ファイルの数、ファイルの tempdb 増加の増分、および最大サイズを設定できます。 Azure SQL Managed Instance のtempdb 設定の構成に関する詳細については、「Azure SQL Managed Instance のtempdb 設定を構成する」を参照してください。

Azure SQL Managed Instance では、SQL Server と同じ方法で一時オブジェクトがサポートされています。この場合、すべてのグローバル一時テーブルとグローバル一時ストアド プロシージャには、同じ SQL マネージド インスタンス内のすべてのユーザー セッションからアクセスできます。

Azure SQL Managed Instance での tempdb のサイズの詳細については、リソース制限に関する記事を参照してください。

Fabric の SQL データベースの tempdb

Microsoft Fabric の SQL データベースの tempdb サイズの詳細については、「機能の比較: Microsoft Fabricの Azure SQL Database と SQL Database」のリソース制限に関するセクションを参照してください。

Azure SQL Database と同様に、Microsoft Fabric の SQL データベース のグローバル一時テーブルはデータベースレベルのスコープを持ちます。 詳細については、Azure SQL Database の データベース スコープのグローバル一時テーブルを参照してください。

制限

tempdb データベースでは、次の操作を実行できません。

  • ファイル グループの追加。
  • データベースのバックアップまたは復元。
  • 照合順序の変更。 既定の照合順序はサーバーの照合順序です。
  • データベース所有者の変更。 tempdbsa によって所有されます。
  • データベース スナップショットの作成。
  • データベースの削除。
  • データベースからの guest ユーザーの削除。
  • 変更データ キャプチャの有効化。
  • データベース ミラーリングへの参加。
  • プライマリ ファイル グループ、プライマリ データ ファイル、またはログ ファイルの削除。
  • データベース名またはプライマリ ファイル グループ名の変更。
  • DBCC CHECKALLOC の実行。
  • DBCC CHECKCATALOG の実行。
  • データベースの OFFLINE への設定。
  • データベースまたはプライマリ ファイル グループの READ_ONLY への設定。

アクセス許可

すべてのユーザーが tempdb 内に一時オブジェクトを作成できます。

ユーザーは、追加のアクセス許可を受け取る場合を除き、tempdb内の一時オブジェクト以外の独自のオブジェクトにのみアクセスできます。

tempdb に対する CONNECT 権限 取り消、データベースユーザーまたはロールが tempdbを使用できないようにすることができます。 多くの操作では tempdbを使用する必要があるため、これはお勧めしません。

SQL Server でクエリのパフォーマンスを最適化する

tempdb ファイルのサイズと物理的な配置は、パフォーマンスに影響する可能性があります。 たとえば、tempdb の初期サイズが小さすぎる場合、データベース エンジン インスタンスが再起動されるたびに、ワークロードをサポートするために必要なサイズに tempdb 自動拡張するために時間とリソースが必要になることがあります。

  • 可能であれば、ファイルの瞬時初期化 を使用して、データ ファイルの拡張操作のパフォーマンスを向上させます。
  • すべての tempdb ファイルに対する領域をあらかじめ割り当てるには、環境における一般的なワークロードに十分に対応できる大きさの値にファイル サイズを設定します。 事前割り当てにより、tempdb が頻繁に自動拡張されるのを防ぎ、パフォーマンスに悪影響を与える可能性があります。
  • tempdb データベース内のファイルを自動拡張に設定して、計画外の拡張イベント中に領域を提供する必要があります。
  • tempdb を等しいサイズの複数のデータ ファイルに分割すると、tempdbを使用する操作の効率が向上します。
    • データ割り当ての不均衡を回避するには、データベース エンジンは、空き領域が多いファイルの割り当てを優先する比例フィル アルゴリズムを使用するため、データ ファイルの初期サイズと拡張パラメーターは同じである必要があります。
    • ファイルの増加の増分を適切なサイズ (64 MB など) に設定し、増加の不均衡を防ぐために、すべてのデータ ファイルで増加増分を同じにします。

tempdb の現在のサイズと拡張パラメーターを確認するには、次のクエリを使用します。

SELECT name AS file_name,
       type_desc AS file_type,
       size * 8.0 / 1024 AS size_mb,
       max_size * 8.0 / 1024 AS max_size_mb,
       CAST(IIF(max_size = 0, 0, 1) AS bit) AS is_autogrowth_enabled,
       CASE WHEN growth = 0 THEN growth
            WHEN growth > 0 AND is_percent_growth = 0 THEN growth * 8.0 / 1024
            WHEN growth > 0 AND is_percent_growth = 1 THEN growth
       END
       AS growth_increment_value,
       CASE WHEN growth = 0 THEN 'Autogrowth is disabled.'
            WHEN growth > 0 AND is_percent_growth = 0  THEN 'Megabytes'
            WHEN growth > 0 AND is_percent_growth = 1  THEN 'Percent'
       END
       AS growth_increment_value_unit
FROM tempdb.sys.database_files;

高速な I/O サブシステムに tempdb データベースを配置します。 個々のデータ ファイルまたは tempdb データ ファイルのグループは、ディスク レベルの I/O ボトルネックが発生しない限り、必ずしも異なるディスク上にある必要はありません。

tempdb データベースとユーザー データベースの間で I/O の競合がある場合は、ユーザー データベースが使用するディスクとは異なるディスクに tempdb ファイルを配置します。

Note

パフォーマンスを向上させるために、データベース オプション DELAYED_DURABILITYDISABLEDに設定されている場合でも、tempdb で遅延持続性 が常に有効tempdb は起動時に再作成されるため、復旧プロセスは行われず、持続性の保証も提供されません。

SQL Server の tempdb でのパフォーマンスの強化

SQL Server 2016 (13.x) で導入されています。

  • 一時テーブルとテーブル変数はキャッシュされます。 キャッシュを使用することで、一時オブジェクトを削除および作成する操作を非常に高速に実行できます。 また、キャッシュによって、ページの割り当てやメタデータの競合も減少します。
  • 割り当てページ ラッチ プロトコルが改善され、使用される UP (更新) ラッチの回数が減っています。
  • tempdb のログ記録オーバーヘッドが減少し、tempdb ログ ファイルのディスク I/O 帯域幅消費が減少しました。
  • SQL セットアップでは、新しいインスタンスのインストール中に複数の tempdb データ ファイルが追加されます。 推奨事項を確認し、SQL セットアップの データベース エンジン構成 ページで tempdb を構成するか、コマンド ライン パラメーター /SQLTEMPDBFILECOUNTを使用します。 既定では、SQL セットアップでは、論理プロセッサの数または 8 つのいずれか小さい方の数の tempdb データ ファイルが追加されます。
  • 複数の tempdb データ ファイルがある場合は、拡張設定に応じて、すべてのファイルが同時に同量ずつ自動拡張されます。 トレース フラグ 1117 は必須ではなくなりました。 詳細については、TEMPDB およびユーザー データベースの -T1117 および -T1118 の変更点を参照 してください。
  • tempdb 内のすべての割り当てで単一エクステントが使用されます。 トレース フラグ 1118 は必須ではなくなりました。 tempdb でのパフォーマンス向上の詳細については、TEMPDB - ファイルとトレース フラグと更新に関するブログ記事を参照してください。
  • AUTOGROW_ALL_FILES プロパティは、PRIMARY ファイル グループに対して常にオンになります。

SQL Server 2017 (14.x) で導入されています。

  • SQL セットアップ エクスペリエンスにより、初期 tempdb ファイル割り当てのガイダンスが向上します。 SQL セットアップでは、インスタンスの起動遅延を防ぐため、初期ファイル サイズが 1 GB を超える値に設定されている場合、およびファイルの瞬時初期化が有効になっていない場合に警告が表示されます。
  • sys.dm_tran_version_store_space_usage 動的管理ビューでは、データベースごとのバージョン ストアの使用状況が追跡されます。 この DMV は、データベースごとのバージョン ストアの使用要件に基づいて tempdb サイズ設定を事前に計画する DBA に役立ちます。
  • インテリジェントなクエリ処理 アダプティブ結合やメモリ許可フィードバックなどの機能により、クエリの連続実行時のメモリ スピルが削減され、tempdb 使用率が低下します。

SQL Server 2019 (15.x) で導入されています。

  • データベース エンジンでは、最大ディスク スループットを実現するために tempdb ファイルを開くときに、FILE_FLAG_WRITE_THROUGH オプションは使用されません。 tempdb は起動時に再作成されるため、このオプションはデータの持続性を提供するために必要ありません。 FILE_FLAG_WRITE_THROUGH の詳細については、「SQL Serverでのデータの信頼性を拡張するログ記録アルゴリズムとデータ ストレージ アルゴリズム」を参照してください。
  • メモリ最適化された TempDB メタデータ は、tempdbにおける一時オブジェクトメタデータの競合を解消します。
  • ページ空き領域 (PFS) ページの同時更新により、すべてのデータベースでのページ ラッチの競合が軽減されます。これは、tempdbで最もよく見られる問題です。 この改善により、PFS ページ更新のコンカレンシー管理が変更され、排他ラッチではなく共有ラッチで更新できるようになります。 この動作は、SQL Server 2019 (15.x) 以降のすべてのデータベース (tempdbを含む) で既定でオンになっています。 PFS ページの詳細については、「内部のしくみ:GAM、SGAM、PFS ページ」を参照してください。
  • 既定では、Linux 上に SQL Server を新しくインストールすると、論理コアの数に基づいて複数の tempdb データ ファイルが作成されます (最大で 8 個のデータ ファイル)。 これは、マイナー バージョンまたはメジャー バージョンのインプレース アップグレードには適用されません。 各 tempdb データ ファイルは 8 MB で、自動拡張は 64 MB です。 この動作は、Windows への SQL Server の既定のインストールに似ています。

SQL Server 2022 (16.x) で導入されています。

メモリ最適化されたTempDBメタデータ

一時的なオブジェクト メタデータの競合は、これまで、多くの SQL Server ワークロードのスケーラビリティのボトルネックでした。 これに対処するために、SQL Server 2019 (15.x) では、メモリ内データベース 機能ファミリの一部である、メモリ最適化 TempDB メタデータの一部である機能が導入されました。

メモリ最適化 TempDB メタデータ機能を有効にすると、tempdb内の一時的なオブジェクト メタデータの競合によって以前に制限されていたワークロードのこのボトルネックが解消されます。 SQL Server 2019 (15.x) 以降では、一時オブジェクト メタデータの管理に関連するシステム テーブルが、ラッチフリーで非永続的なメモリ最適化テーブルになる可能性があります。

ヒント

現在の 制限があるため、メモリ最適化 TempDB メタデータは、オブジェクト メタデータの競合が発生し、ワークロードに大きな影響を与える場合にのみ有効にすることをお勧めします。

次の診断クエリは、一時的なオブジェクト メタデータの競合が発生している場合に 1 つ以上の行を返します。 各行は、システム テーブルを表し、この診断クエリの実行時にそのテーブルにアクセスするために競合するセッションの数を返します。

SELECT OBJECT_NAME(dpi.object_id, dpi.database_id) AS system_table_name,
       COUNT(DISTINCT(r.session_id)) AS session_count
FROM sys.dm_exec_requests AS r
CROSS APPLY sys.fn_PageResCracker(r.page_resource) AS prc
CROSS APPLY sys.dm_db_page_info(prc.db_id, prc.file_id, prc.page_id, 'LIMITED') AS dpi
WHERE dpi.database_id = 2
      AND dpi.object_id IN (3, 9, 34, 40, 41, 54, 55, 60, 74, 75)
      AND UPPER(r.wait_type) LIKE N'PAGELATCH[_]%'
GROUP BY dpi.object_id, dpi.database_id;

メモリ最適化 TempDB メタデータ機能を使用する方法とタイミングの概要については、この 7 分間のビデオをご覧ください。

Note

現在、メモリ最適化 TempDB メタデータ機能は、Azure SQL Database、Microsoft Fabric の SQL データベース、および Azure SQL Managed Instance では使用できません。

メモリ最適化 TempDB メタデータの構成と使用

次のセクションでは、メモリ最適化 TempDB メタデータ機能を有効、構成、検証、無効化する手順について説明します。

有効にする

この機能を有効にするには、次のスクリプトを使用します。

ALTER SERVER CONFIGURATION SET MEMORY_OPTIMIZED TEMPDB_METADATA = ON;

詳細については、「ALTER SERVER」を参照してください。 この構成の変更を有効にするには、サービスの再起動が必要です。

次の T-SQL コマンドを使用して、tempdb がメモリ最適化かどうかを確認できます。

SELECT SERVERPROPERTY('IsTempdbMetadataMemoryOptimized');

戻り値が 1 で、機能を有効にした後に再起動が発生した場合、機能は有効になります。

メモリ最適化 TempDB メタデータを有効にした後に何らかの理由でサーバーの起動に失敗した場合は、-f スタートアップ オプションを使用して最小限の構成 でデータベース エンジン インスタンス 開始することで、この機能をバイパスできます。 その後、機能 無効にし、-f オプションを削除して、通常モードでデータベース エンジンを再起動できます。

リソース プールにバインドしてメモリ使用量を制限する

メモリ不足状態からサーバーを保護するには、メモリ最適化 TempDB メタデータによって消費されるメモリを制限するリソース ガバナー リソース プールtempdb をバインドすることをお勧めします。 次のサンプル スクリプトでは、リソース プールを作成し、その最大メモリを 20%に設定し、リソース ガバナー 有効にして、リソース プールに tempdb バインドします。

この例では、デモンストレーション用のメモリ制限として 20% を使用します。 環境内の最適な値は、ワークロードによっては大きくても小さくなり、ワークロードが変化すると時間の経過と同時に変化する可能性があります。

CREATE RESOURCE POOL tempdb_resource_pool
WITH (MAX_MEMORY_PERCENT = 20);

ALTER RESOURCE GOVERNOR RECONFIGURE;

ALTER SERVER CONFIGURATION 
SET MEMORY_OPTIMIZED TEMPDB_METADATA = ON 
(RESOURCE_POOL = 'tempdb_resource_pool');

この変更では、メモリ最適化 TempDB メタデータが既に有効になっている場合でも、サービスの再起動を有効にする必要があります。

リソース プールのバインドを確認し、メモリ使用量を監視する

tempdb がリソース プールにバインドされていることを確認し、プールのメモリ使用量の統計情報を監視するには、次のクエリを使用します。

WITH resource_pool AS
(
SELECT p.pool_id,
       p.name,
       p.max_memory_percent,
       dp.max_memory_kb,
       dp.target_memory_kb,
       dp.used_memory_kb,
       dp.out_of_memory_count
FROM sys.resource_governor_resource_pools AS p
INNER JOIN sys.dm_resource_governor_resource_pools AS dp
ON p.pool_id = dp.pool_id
)
SELECT SERVERPROPERTY('IsTempdbMetadataMemoryOptimized') AS is_tempdb_memory_optimized_metadata_enabled,
       rp.name AS resource_pool_name,
       rp.max_memory_percent,
       rp.max_memory_kb,
       rp.target_memory_kb,
       rp.used_memory_kb,
       rp.out_of_memory_count
FROM sys.databases AS d
LEFT JOIN resource_pool AS rp
ON d.resource_pool_id = rp.pool_id
WHERE d.name = 'tempdb';

リソース プールのバインドを削除する

メモリ最適化 TempDB メタデータを有効にしたままリソース プールのバインドを削除するには、次のコマンドを実行してサービスを再起動します。

ALTER SERVER CONFIGURATION 
SET MEMORY_OPTIMIZED TEMPDB_METADATA = ON;

無効にする

メモリ最適化 TempDB メタデータを無効にするには、次のコマンドを実行し、サービスを再起動します。

ALTER SERVER CONFIGURATION 
SET MEMORY_OPTIMIZED TEMPDB_METADATA = OFF;

メモリ最適化 TempDB メタデータの制限事項

  • メモリ最適化 TempDB メタデータ機能を有効または無効にするには、再起動が必要です。

  • 場合によっては、MEMORYCLERK_XTP メモリ クラークによってメモリ使用量が多くなり、ワークロードでメモリ不足エラーが発生することがあります。

    MEMORYCLERK_XTP クラークによるメモリ使用量を他のすべてのメモリ クラークに対して、およびターゲット サーバー メモリに対して相対的に確認するには、次のクエリを実行します。

    SELECT SUM(IIF(type = 'MEMORYCLERK_XTP', pages_kb, NULL)) / 1024. AS memoryclerk_xtp_pages_mb,
           SUM(IIF(type <> 'MEMORYCLERK_XTP', pages_kb, NULL)) / 1024. AS other_pages_mb,
           SUM(committed_target_kb) / 1024. AS committed_target_memory_mb
    FROM sys.dm_os_memory_clerks
    CROSS JOIN sys.dm_os_sys_info;
    

    MEMORYCLERK_XTP メモリが大きい場合は、次のように問題を軽減できます。

    • メモリ最適化 TempDB メタデータによるメモリ使用量を制限するリソース プールに tempdb データベースをバインドします。 詳細については、「メモリ最適化 tempdb メタデータの構成と使用」を参照してください。
    • システム ストアド プロシージャを定期的に実行して、不要になったメモリ MEMORYCLERK_XTP 解放できます。 詳細については、「ys.sp_xtp_force_gc (Transact-SQL)」を参照してください。

    詳細については、メモリ最適化された tempdb メタデータ (HkTempDB) のメモリ不足エラーを参照してください。

  • In-Memory OLTPを使用する場合、1 つのトランザクションで複数のデータベース内のメモリ最適化テーブルにアクセスすることはできません。 このため、ユーザー データベース内のメモリ最適化テーブルを含む読み取りまたは書き込みトランザクションは、同じトランザクション tempdb システム ビューにもアクセスできません。 この場合、エラー 41317 が表示されます。

    A user transaction that accesses memory optimized tables or natively compiled modules cannot access more than one user database or databases model and msdb, and it cannot write to master.
    

    この制限は、1 つのトランザクションが複数のデータベース内のメモリ最適化テーブルにアクセスしようとする他のシナリオにも適用されます。

    たとえば、メモリ最適化テーブルを含むユーザー データベースで sys.stats カタログ ビュー クエリを実行すると、エラー 41317 が発生する可能性があります。 これは、クエリがユーザー データベース内のメモリ最適化テーブル データと、tempdb内のメモリ最適化メタデータ 統計にアクセスしようとするためです。

    次のサンプル スクリプトは、メモリ最適化 TempDB メタデータが有効になっている場合にこのエラーを生成します。

    BEGIN TRAN;
    
    -- Create an In-memory OLTP transaction that accesses a system view in tempdb
    SELECT name
    FROM tempdb.sys.tables;
    
    -- An attempt to create an In-memory OLTP transaction in the user database fails
    INSERT INTO <user database>.<schema>.<memory-optimized table>
    VALUES (1);
    
    COMMIT TRAN;
    

    Note

    この制限は、一時テーブルには適用されません。 ユーザー データベース内のメモリ最適化テーブルにアクセスするのと同じトランザクションに一時テーブルを作成できます。

  • システム カタログ ビューに対するクエリでは、常に READ COMMITTED 分離レベルが使用されます。 メモリ最適化 TempDB メタデータが有効になっている場合、tempdb のシステム カタログ ビューに対するクエリでは、SNAPSHOT 分離レベルが使用されます。 どちらの場合も、ロック ヒントは使用されません。

  • メモリ最適化 TempDB メタデータが有効になっている場合、一時テーブルに列ストア インデックスを作成することはできません。

    • その結果、メモリ最適化 TempDB メタデータが有効になっている場合、COLUMNSTORE または COLUMNSTORE_ARCHIVE データ圧縮パラメーターを使用した sp_estimate_data_compression_savings システム ストアド プロシージャの使用はサポートされません。

SQL Server での tempdb の容量計画

tempdb の適切なサイズの決定は、多くの要因によって異なります。 これらの要因には、ワークロードと、使用されるデータベース エンジンの機能が含まれます。

一般的なワークロードを再現できるテスト環境で次のタスクを実行して、tempdb 領域の消費量を分析することをお勧めします。

  • 自動拡張tempdb ファイルに対して有効にします。 すべての tempdb データ ファイルの初期サイズと自動拡張の構成は同じである必要があります。
  • ワークロードを再現し、tempdb 領域の使用を監視します。
  • 定期的な インデックスメンテナンスを使用する場合は、メンテナンス ジョブを実行し、tempdb 領域を監視します。
  • 前の手順で使用した最大領域の値を使用して、ワークロードの合計使用量を予測します。 予測される同時実行アクティビティに対してこの値を調整した後、それに応じて tempdb のサイズを設定します。

tempdb の使用の監視

tempdb のディスク領域が不足すると、重大な中断とアプリケーションのダウンタイムが発生する可能性があります。 sys.dm_db_file_space_usage 動的管理ビューを使用して、tempdb ファイルで使用されている領域を監視できます。

たとえば、次のスクリプトの例では、次のような検索が行われます。

  • tempdb の空き領域 (tempdb の拡張に使用できる可能性がある空きディスク領域は考慮しません)
  • バージョン ストアで使用される領域
  • 内部オブジェクトによって使用されるスペース
  • ユーザー オブジェクトで使用される領域
SELECT SUM(unallocated_extent_page_count) * 8.0 / 1024 AS tempdb_free_data_space_mb,
       SUM(version_store_reserved_page_count) * 8.0 / 1024 AS tempdb_version_store_space_mb,
       SUM(internal_object_reserved_page_count) * 8.0 / 1024 AS tempdb_internal_object_space_mb,
       SUM(user_object_reserved_page_count) * 8.0 / 1024 AS tempdb_user_object_space_mb
FROM tempdb.sys.dm_db_file_space_usage;

セッション レベルまたはタスク レベルで tempdb のページ割り当てまたは割り当て解除アクティビティを監視するには、sys.dm_db_session_space_usagesys.dm_db_task_space_usage 動的管理ビューを使用できます。 これらのビューは、大量の tempdb 領域を使用しているクエリ、一時テーブル、またはテーブル変数を識別するのに役立ちます。

たとえば、次のサンプル スクリプトを使用して、各セッションで現在実行中のすべてのタスクで内部オブジェクトによって割り当ておよび割り当て解除された tempdb 領域を取得します。

SELECT session_id,
       SUM(internal_objects_alloc_page_count) AS task_internal_objects_alloc_page_count,
       SUM(internal_objects_dealloc_page_count) AS task_internal_objects_dealloc_page_count
FROM sys.dm_db_task_space_usage
GROUP BY session_id;

次のサンプル スクリプトを使用して、実行中のタスクと完了したタスクの両方について、セッションと要求ごとに内部オブジェクトとユーザー オブジェクトによって割り当てられ、現在使用されている tempdb 領域を見つけます。

WITH tempdb_space_usage AS
(
SELECT session_id,
       request_id,
       user_objects_alloc_page_count + internal_objects_alloc_page_count AS tempdb_allocations_page_count,
       user_objects_alloc_page_count + internal_objects_alloc_page_count - user_objects_dealloc_page_count - internal_objects_dealloc_page_count AS tempdb_current_page_count
FROM sys.dm_db_task_space_usage
UNION ALL
SELECT session_id,
       NULL AS request_id,
       user_objects_alloc_page_count + internal_objects_alloc_page_count AS tempdb_allocations_page_count,
       user_objects_alloc_page_count + internal_objects_alloc_page_count - user_objects_dealloc_page_count - user_objects_deferred_dealloc_page_count - internal_objects_dealloc_page_count AS tempdb_current_page_count
FROM sys.dm_db_session_space_usage
)
SELECT session_id,
       COALESCE(request_id, 0) AS request_id,
       SUM(tempdb_allocations_page_count * 8) AS tempdb_allocations_kb,
       SUM(IIF (tempdb_current_page_count >= 0, tempdb_current_page_count, 0) * 8) AS tempdb_current_kb
FROM tempdb_space_usage
GROUP BY session_id, COALESCE (request_id, 0)
ORDER BY session_id, request_id;