tempdb データベース
適用対象: SQL Server
Azure SQL Database
Azure SQL Managed Instance
Microsoft Fabric SQL Database
この記事では、tempdb
システム データベース、SQL Server、Azure SQL Database、または Azure SQL Managed Instance のデータベース エンジン インスタンスに接続されているすべてのユーザーが使用できるグローバル リソースについて説明します。
概要
tempdb
システム データベースは、次のものを保持するグローバル リソースです。
ユーザーオブジェクト が明示的に作成される 場合。 それには次の内容を含みます。
- グローバルまたはローカルの一時テーブルと、これらのテーブル上のインデックス
- 一時ストアドプロシージャ
- テーブル変数
- テーブル値関数で返されるテーブル
- カーソル
ユーザー データベースで作成できるユーザー オブジェクトは、
tempdb
でも作成できますが、持続性を保証せずに作成され、データベース エンジン インスタンスの再起動時に削除されます。データベース エンジンによって作成された "内部オブジェクト"。 それには次の内容を含みます。
- スプール、カーソル、並べ替え、および一時的なラージ オブジェクト (LOB) 記憶域の中間結果を格納する作業テーブル。
- ハッシュ結合操作またはハッシュ集計操作用の作業ファイル
- インデックスの作成または再構築などの操作 (
SORT_IN_TEMPDB
が指定されている場合) や、GROUP BY
、ORDER BY
、UNION
などの特定のクエリにおける、並べ替えの中間結果。
各内部オブジェクトでは、少なくとも 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
の現在のサイズと増加のパラメーターを確認するには、tempdb
の sys.database_files カタログ ビューを使用します。
SQL Server の tempdb のデータ ファイルとログ ファイルの移動
tempdb
のデータ ファイルとログ ファイルを移動するには、「システム データベースの移動」を参照してください。
SQL Server での tempdb のデータベース オプション
tempdb
データベースの各データベース オプションの既定値とそのオプションを変更できるかどうかを次の表に示します。 これらのオプションの現在の設定を表示するには、 sys.databases カタログ ビューを使用します。
これらのデータベース オプションの説明は、「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
のサイズの詳細については、次を確認してください。
- 仮想コア購入モデル: 単一データベース、プールされたデータベース
- DTU 購入モデル: 単一データベース、プールされたデータベース
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
データベースでは、次の操作を実行できません。
- ファイル グループの追加。
- データベースのバックアップまたは復元。
- 照合順序の変更。 既定の照合順序はサーバーの照合順序です。
- データベース所有者の変更。
tempdb
は sa によって所有されます。 - データベース スナップショットの作成。
- データベースの削除。
- データベースからの guest ユーザーの削除。
- 変更データ キャプチャの有効化。
- データベース ミラーリングへの参加。
- プライマリ ファイル グループ、プライマリ データ ファイル、またはログ ファイルの削除。
- データベース名またはプライマリ ファイル グループ名の変更。
-
DBCC CHECKALLOC
の実行。 -
DBCC CHECKCATALOG
の実行。 - データベースの
OFFLINE
への設定。 - データベースまたはプライマリ ファイル グループの
READ_ONLY
への設定。
アクセス許可
すべてのユーザーが tempdb
内に一時オブジェクトを作成できます。
ユーザーは、追加のアクセス許可を受け取る場合を除き、tempdb
内の一時オブジェクト以外の独自のオブジェクトにのみアクセスできます。
tempdb
に対する CONNECT
権限 取り消、データベースユーザーまたはロールが tempdb
を使用できないようにすることができます。 多くの操作では tempdb
を使用する必要があるため、これはお勧めしません。
SQL Server でクエリのパフォーマンスを最適化する
tempdb
ファイルのサイズと物理的な配置は、パフォーマンスに影響する可能性があります。 たとえば、tempdb
の初期サイズが小さすぎる場合、データベース エンジン インスタンスが再起動されるたびに、ワークロードをサポートするために必要なサイズに tempdb
自動拡張するために時間とリソースが必要になることがあります。
- 可能であれば、ファイルの瞬時初期化 を使用して、データ ファイルの拡張操作のパフォーマンスを向上させます。
- SQL Server 2022 (16.x) 以降では、最大 64 MB のトランザクション ログ ファイル拡張イベントは、ファイルの瞬時初期化のメリットも得られます。 詳細については、「ファイルの瞬時初期化とトランザクション ログの」を参照してください。
- すべての
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_DURABILITY
が DISABLED
に設定されている場合でも、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) で導入されています。
- システム ページ ラッチコンカレンシー 強化されたスケーラビリティ導入しました。 グローバル アロケーション マップ (GAM) ページと共有グローバル アロケーション マップ (SGAM) ページへの同時更新により、データ ページとエクステントの割り当てまたは割り当て解除中のページ ラッチの競合が軽減されます。 これらの機能強化は、すべてのユーザー データベースに適用され、
tempdb
の負荷の高いワークロードに特に役立ちます。 GAM ページと SGAM ページの詳細については、「内部のしくみ: GAM、SGAM、および PFS ページ」を参照してください。 詳細については、「システム ページ ラッチ コンカレンシーの強化(Ep. 6)」| 公開されているデータ」を参照してください。
メモリ最適化された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) のメモリ不足エラーを参照してください。
- メモリ最適化 TempDB メタデータによるメモリ使用量を制限するリソース プールに
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
システム ストアド プロシージャの使用はサポートされません。
- その結果、メモリ最適化 TempDB メタデータが有効になっている場合、
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_usage と sys.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;