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

相關文章
相關標籤/搜索