SQL Server里在文件组间如何移动数据?

日常我不知道被问了几回这样的问题:“SQL  Server里在文件组间如何移动数据?“你意识到这个问题:你只有一个主文件组的默认配置,后来围观了“SQL Server里的文件和文件组”后,你知道,有多个文件的自定义文件组会是个更好的主意。但你如今如何从主文件组里移动现有数据到新加的文件组?html

这篇文章的目的是向你展现你如何在文件组间移动数据。首先我会谈下汇集和非汇集索引,而后我会谈下如何在堆表里移动数据。让咱们开始吧!sql

移动汇集和非汇集索引

通常来讲在你的表上一般应该有一个汇集索引。有了现存的汇集索引就很容易移动表数据(即汇集索引)到不一样的文件组。下列代码我为表建立了一个简单的汇集和非汇集索引,并插入近800MB的测试数据到表。测试

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个索引(汇集索引和非汇集苏音)。spa

sp_help TestTable

假设如今我已经让你相信一个有多个文件的自定义文件组是个好主意,而且你付诸行动了:code

-- 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里获得):server

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已经讲汇集索引彻底移入不一样的文件组。htm

如今咱们继续处理非汇集索引:blog

-- 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的数据,你最终能够验证新分配在新加的文件组里发生,主文件组仍是很小。搞定!ip

移动堆表

若是你想从堆表移动数据到自定义的文件组,这须要一点技巧。主要的问题是SQL Server不提供在文件组间移动堆表数据的方法。

所以咱们要变通下:你在堆表上临时建立一个汇集索引(会把数据移入自定义文件组),而后你删除汇集索引恢复为堆表。

-- 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

我知道这样有点奇怪,但没有其余更高效的方法。另外一个方法是在自定义文件组里建立新的堆表,移动数据到新的堆表,删除原来的堆表,重命名新的堆表。还不是一个完美的解决方法……

小结

在文件组间移动数据能够简单也能够复杂——取决于有没有汇集索引存在。若是你有汇集索引,你只须要在自定义文件组重建索引便可。若是你要处理堆表,你要临时增长汇集索引(它会移动表数据到别的文件组),而后删除汇集索引。真的不是个完美的解决方法……

感谢关注!

原文连接

https://www.sqlpassion.at/archive/2016/09/26/how-to-move-data-between-file-groups-in-sql-server

相关文章
相关标签/搜索