現象
Microsoft SQL Server 2008、SQL Server 2008 R2、SQL Server 2012、または SQL Server 2014 に大きなオブジェクト (LOB) 列を含むテーブルがあるとします。 LOB データのサイズを小さくして LOB 列を更新し、次の方法を使用して未使用領域を再利用しようとする場合:
- DBCC SHRINKDATABASE / DBCC SHRINKFILE
- ALTER INDEX REORGANIZE WITH (LOB_COMPACTION = ON)
この状況では、未使用の領域を再利用することはできません。
解決策
この問題は、次の SQL Server の累積的な更新プログラムで最初に修正されました。
SQL Server 2012 SP2 の累積的な更新プログラム 2 /en-us/help/2983175
SQL Server 2012 SP1 の累積的な更新プログラム 11 /en-us/help/2975396
SQL Server 2008 R2 SP2 の累積的な更新プログラム 13 /en-us/help/2967540
SQL Server 2014 用の累積的な更新プログラム 2 /en-us/help/2967546
SQL Server 2008 SP3 の累積的な更新プログラム 17 /en-us/help/2958696
SQL Server 用の累積的な更新プログラムについて
SQL Server 用の新しい累積的な更新プログラムには、以前の累積的な更新プログラムに含まれていたすべての修正プログラムとすべてのセキュリティ修正プログラムが含まれています。 SQL Server の最新の累積的な更新プログラムを確認してください。
- SQL Server 2012 SP2 の最新の累積的な更新プログラム
- SQL Server 2012 SP1 の最新の累積的な更新プログラム
- SQL Server 2008 R2 SP2 の最新の累積的な更新プログラム
- SQL Server 2014 の最新の累積的な更新プログラム
- SQL Server 2008 SP3 の最新の累積的な更新プログラム
回避策
この問題を回避するには、次の回避策を使用します。
- すべての行を新しいテーブルにエクスポートし、行を元に戻します。 これにより、LOB データが再編成され、未使用の領域が解放されます。
- DBCC SHRINKFILE と EMPTYFILE オプションを使用して、すべてのデータを新しく追加したデータ ファイルに移動し、古いデータ ファイルを削除します。 これにより、未使用の領域が解放され、LOB データが再編成されます。
追加情報
次の例は、LOB データのサイズを小さくして LOB 列を更新する前後の TSQL コマンドsp_spaceused 'table_name' を使用して、未使用領域を示しています。
更新の前に:
| 名前 | 行 | reserved | data | index_size | 未使用 |
|---|---|---|---|---|---|
| table_name | 1000 | 261072 KB | 261056 KB | 16 KB | 0 KB |
更新後:
| 名前 | 行 | reserved | data | index_size | 未使用 |
|---|---|---|---|---|---|
| table_name | 1000 | 261072 KB | 199672 KB | 16 KB | 61384 KB |
状態
Microsoft は、これが "適用対象" セクションに記載されている Microsoft 製品の問題であることを確認しました。