CREATE TABLE TestTable
(
ID INT IDENTITY(1, 1) PRIMARY KEY NOT NULL,
SomeData1 INT NOT NULL,
SomeData2 CHAR(5000)
)
GO
-- Create a supporting Non-Clustered Index
CREATE NONCLUSTERED INDEX idx_SomeData1 ON TestTable(SomeData1)
GO
-- Insert around 800 MB of data
DECLARE @i INT = 0
WHILE (@i < 100000)
BEGIN
INSERT INTO TestTable (SomeData1, SomeData2)
VALUES (@i, REPLICATE('a', 5000))
SET @i += 1
END
GO
但你在表上执行sp_help的系统存储过程,你可以看到在主文件组里看到2个索引(聚集索引和非聚集苏音)。
sp_help TestTable
假设现在我已经让你相信一个有多个文件的自定义文件组是个好主意,并且你付诸行动了:
-- Add a new file group to the database
ALTER DATABASE MultipleFileGroups ADD FILEGROUP CustomFileGroup
GO
-- Add a new file to the previous created file group
ALTER DATABASE MultipleFileGroups ADD FILE
(
NAME = 'CustomFile1',
FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL11.SQL2012\MSSQL\DATA\CustomFile1.ndf',
SIZE = 1048576KB,
FILEGROWTH = 65536KB
) TO FILEGROUP CustomFileGroup
GO
-- Add a new file to the previous created file group
ALTER DATABASE MultipleFileGroups ADD FILE
(
NAME = 'CustomFile2',
FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL11.SQL2012\MSSQL\DATA\CustomFile2.ndf',
SIZE = 1048576KB,
FILEGROWTH = 65536KB
) TO FILEGROUP CustomFileGroup
GO
现在的问题是现存的你的所有数据还在主文件组。你如何移动它们到新加的文件组?这个问题的答案非常简单:重建这些索引(聚集和非聚集索引)即可,并且指定新加的文件组作为目标!我们先从聚集索引开始(索引名称从sys.index里得到):
SELECT * FROM sys.indexes WHERE object_id=OBJECT_ID('TestTable')
-- Move the Clustered Index into the newly created file group
CREATE UNIQUE CLUSTERED INDEX PK__TestTabl__3214EC27D9EE93A9 ON TestTable(ID)
WITH
(
DROP_EXISTING = ON
)
ON CustomFileGroup
GO
当你再次执行sp_help,你会看到SQL Server已经讲聚集索引完全移入不同的文件组。
现在我们继续处理非聚集索引:
-- Create a supporting Non-Clustered Index
CREATE NONCLUSTERED INDEX idx_SomeData1 ON TestTable(SomeData1)
WITH
(
DROP_EXISTING = ON
)
ON CustomFileGroup
GO
最后,我们可以收缩主文件组的数据文件来回收已分配的空间:
-- Shrink the MDF file in the PRIMARY file group
DBCC SHRINKFILE ('TestDatabase' , 0)
GO
现在当你插入另一个800MB的数据,你最终可以验证新分配在新加的文件组里发生,主文件组还是很小。搞定!
-- Create a new Clustered Index on the Heap table that moves the data into the custom file group
CREATE UNIQUE CLUSTERED INDEX idx_ci ON TestTable(ID)
ON CustomFileGroup
GO
-- Drop the previous created Clustered Index again ;-)
DROP INDEX idx_ci ON TestTable
GO
我知道这样有点奇怪,但没有其他更高效的方法。另一个方法是在自定义文件组里创建新的堆表,移动数据到新的堆表,删除原来的堆表,重命名新的堆表。还不是一个完美的解决方法……