DELETE ステートメントを使用して SQL Server 内のテーブルからデータを削除した後、テーブルが使用する領域は完全には解放されません。
この記事は、DELETE ステートメントを使用してテーブルからすべてのデータを削除した後に、テーブルで使用される問題を解決するのに役立ちます。
元の製品バージョン: SQL Server
元の KB 番号: 913399
現象
Microsoft SQL Server で DELETE ステートメントを使用してテーブルからデータを削除すると、テーブルで使用される領域が完全に解放されないことに気付く場合があります。 その後、データベースにデータを挿入しようとすると、次のエラー メッセージが表示されることがあります。
'PRIMARY' ファイル グループがいっぱいであるため、データベース 'DatabaseName' のオブジェクト 'TableName' の領域を割り当てませんでした。
注:
TableName は、テーブルの名前を表します。 DatabaseName は、テーブルを含むデータベースの名前を表します。
原因
この問題は、SQL Serverが次の条件に該当する場合にヒープ テーブルが使用するすべてのページのみを解放するため発生します。
- このテーブルの削除が発生します。
- テーブル レベルのロックが保持されています。
注:
ヒープ テーブルは、クラスター化インデックスに関連付けられていない任意のテーブルです。
ページの割り当てが解除されていない場合、データベース内の他のオブジェクトはページを再利用できません。
ただし、SQL Server データベースで行versioning-based
分離レベルを有効にすると、テーブル レベルのロックが保持されていてもページを解放できません。 行versioning-based
分離レベルの詳細については、「SQL Server データベース エンジンの分離レベル」を参照してください。
回避策
この問題を回避するには、次のいずれかの方法を使用します。
行のバージョン管理ベースの分離レベルが有効になっていない場合は、DELETE ステートメントに TABLOCK ヒントを含めます。 たとえば、次のようなステートメントを使用します。
DELETE FROM <TableName> WITH (TABLOCK)
注:
<TableName> は、テーブルの名前を表します。
テーブル内のすべてのレコードを削除する場合は、TRUNCATE TABLE ステートメントを使用します。 たとえば、次のようなステートメントを使用します。
TRUNCATE TABLE <TableName>
テーブルの列にクラスター化インデックスを作成します。 テーブルにクラスター化インデックスを作成する方法の詳細については、「クラスター化インデックスの 作成」を参照してください。
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示