6

それぞれ5.5kk行の約300のテーブルがあります。行の 1 つは nvarchar(128) をデータ型として使用しています (SQL Server 2012)。
これを int に変更し、すべての nvarchar を含むディクショナリ テーブルに FK を追加することにしました。

すべてを実行した後、nvarchar 列を削除しましたが、テーブルのサイズは同じままでした。DBCC CLEANTABLE を使用し、インデックスを再構築して空き領域を再利用しましたが、テーブルのサイズはまだ変化していません。

これまでのところ、私が見つけた唯一の方法は、すべてのデータを新しいテーブルにコピーすることです。

質問: ここで何が欠けていますか? スペースがまだ使用済みとしてマークされていて、縮小または CREANTABLE コマンドで解放できないのはなぜですか?

ありがとうございました!

回答:答えはかなり単純なようで、私の知識不足で見つけることができませんでした。ここでの主な問題は、ヒープの断片化でした。このクエリは私のために働いた:

ALTER TABLE [TABLE_NAME] REBUILD

それが最善の方法かどうかはわかりませんが、少なくとも機能する方法です。

Edited1 :申し訳ありませんが、言及するのを忘れていたと思います-テキストフィールドにクラスター化されたインデックスがあったため、実際にフィールドを削除できるようにするには、インデックスを削除する必要がありました。今、私はインデックスを持っていません。

編集済み2 :

古いテーブル:

CREATE TABLE [dbo].[Data_](
    [ID] [bigint] PRIMARY KEY IDENTITY(1,1) NOT NULL,
    [Text] [nvarchar](128) NOT NULL,
    [Category] [tinyint] NOT NULL,
    [Country] [nvarchar](2) NOT NULL,
    [ImportTimestamp] [date] NOT NULL
)

新しいテーブル:

CREATE TABLE [dbo].[Data_New](
    [ID] [int] PRIMARY KEY IDENTITY(1,1) NOT NULL,
    [Category] [tinyint] NOT NULL,
    [Country] [nvarchar](2) NOT NULL,
    [TextID] [int] NOT NULL)

ALTER TABLE [dbo].[Data_New]  WITH CHECK ADD FOREIGN KEY([TextID])
REFERENCES [dbo].[Dictionary] ([Id])

スクリプトをコピー:

INSERT INTO Data_New
      ([Category]
      ,[Country]
      ,[TextID])
SELECT 
      [Category]
      ,[Country]
      ,[TextID]
  FROM Data_
4

2 に答える 2

3

この列の変更により、テーブルが小さくなるはずですか? nvarchar(128) は、SQL Server が文字列 'test' などのデータを保存するために 128 バイト (+2) を割り当てるという意味ではありません。文字列「test」は 6 バイトしか使用しません。最初にテーブルの空き容量を確認する必要があるかもしれません:

SELECT 
    t.NAME AS TableName,
    s.Name AS SchemaName,
    p.rows AS RowCounts,
    SUM(a.total_pages) * 8 AS TotalSpaceKB, 
    SUM(a.used_pages) * 8 AS UsedSpaceKB, 
    (SUM(a.total_pages) - SUM(a.used_pages)) * 8 AS UnusedSpaceKB
FROM 
    sys.tables t
INNER JOIN      
    sys.indexes i ON t.OBJECT_ID = i.object_id
INNER JOIN 
    sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id
INNER JOIN 
    sys.allocation_units a ON p.partition_id = a.container_id
LEFT OUTER JOIN 
    sys.schemas s ON t.schema_id = s.schema_id
WHERE 
    t.NAME = 'TABLE_NAME'
    AND t.is_ms_shipped = 0'
    AND i.OBJECT_ID > 255 
GROUP BY 
    t.Name, s.Name, p.Rows
ORDER BY 
    t.Name
于 2016-04-05T11:12:52.980 に答える