我如何将表移动到另一个文件组?

时间:2010-03-13 10:38:10

标签: sql-server sql-server-2008 filegroup

我有两个大表的SQL Server 2008 Ent和OLTP数据库。如何在不中断服务的情况下将此表移动到另一个文件组?现在,在此表中每秒插入大约100-130条记录和30-50条记录。每个表有大约100M记录和六个字段(包括一个字段地理)。

我通过谷歌寻找解决方案,但所有解决方案都包含“创建第二个表,从第一个表插入行,删除第一个表,bla bla bla”。

我可以使用分区功能来解决这个问题吗?谢谢。

9 个答案:

答案 0 :(得分:72)

如果您只想将表移动到新文件组,则需要在新文件组上重新创建表上的聚簇索引(毕竟:聚簇索引 表数据)想。

您可以使用例如:

执行此操作
CREATE CLUSTERED INDEX CIX_YourTable
   ON dbo.YourTable(YourClusteringKeyFields)
   WITH DROP_EXISTING
   ON [filegroup_name]

或者您的聚集索引唯一

CREATE UNIQUE CLUSTERED INDEX CIX_YourTable
   ON dbo.YourTable(YourClusteringKeyFields)
   WITH DROP_EXISTING
   ON [filegroup_name]

这将创建一个新的聚簇索引并删除现有聚簇索引,并在您指定的文件组中创建新的聚簇索引 - 等等,您的表数据已移至新文件组。

有关您可能要指定的所有可用选项的详细信息,请参阅MSDN docs on CREATE INDEX

这当然还没有涉及分配,但这完全是另一个故事......

答案 1 :(得分:23)

要回答这个问题,首先我们必须了解

  • 如果表没有索引,则其数据称为 heap
  • 如果表具有聚簇索引,则该索引实际上是您的表数据。因此,如果移动聚集索引,您也将移动数据。

第一步是找到有关我们要移动的表的更多信息。我们通过执行此T-SQL来执行此操作:

sp_help N'<<your table name>>'

输出将显示标题为“Data_located_on_filegroup”的列。&#39;这是了解表数据所在的文件组的便捷方法。但更重要的是输出显示有关表索引的信息。 (如果您只想查看有关表索引的信息,只需运行sp_helpindex N'<<your table name>>')您的表可能有1)没有索引(所以它是堆),2)单个索引,或3)多个索引。如果index_description以&clustered,unique,...&#39;开头,那就是您想要移动的索引。如果索引也是主键,那就没问题,你仍然可以移动它。

要移动索引,请记下上述帮助查询结果中显示的index_name和index_keys,然后使用它们填写以下查询中的<<blanks>>

CREATE UNIQUE CLUSTERED INDEX [<<name of clustered index>>]
ON [<<table name>>]([<<column name the index is on - from index_keys above>>])
WITH DROP_EXISTING, ONLINE
ON <<name of file group you want to move the index to>>

上面的DROP EXISTING, ONLINE选项非常重要。 DROP EXISTING确保索引不会重复,ONLINE会在您移动桌面时保持桌面在线。

如果您要移动的索引聚集索引,请将上面的UNIQUE CLUSTERED替换为NONCLUSTERED

要移动堆表,向其中添加聚簇索引,然后运行上述语句将其移动到其他文件组,然后删除索引。

现在,返回并在您的表上运行sp_help,并检查结果以查看您的表和索引数据现在的位置。

如果您的表有多个索引,那么在运行上述语句移动聚簇索引后,sp_helpindex将显示您的聚簇索引位于新文件组中,但是任何剩余的索引仍将在原始文件组中。该表将继续正常运行,但您应该有充分的理由希望索引位于不同的文件组中。如果您希望表及其所有索引位于同一文件组中,请对每个索引重复上述说明,根据您要移动的索引类型,根据需要替换CREATE [NONCLUSTERED, or other] ... DROP EXISTING...

答案 2 :(得分:7)

分区是一种解决方案,但您可以使用

将聚集索引“移动”到新文件组而不会中断服务(受某些条件限制,请参阅下面的链接)
CREATE CLUSTERED /*oops*/ INDEX ... WITH (DROP_EXISTING = ON, ONLINE = ON, ...) ON newfilegroup

聚集索引数据,这与移动文件组相同。

请参阅CREATE INDEX

这取决于您的主键是否已群集,这会改变我们的主要方式

答案 3 :(得分:2)

SQL Server联机丛书的摘录说明了这一点:“因为聚簇索引的叶级别和数据页面的定义相同,所以创建聚簇索引并有效地使用ON partition_scheme_name或ON filegroup_name 子句将表从创建表的文件组移动到新的分区方案或文件组。“ (来源 - http://msdn.microsoft.com/en-us/library/ms188783.aspx)来自(http://www.mssqltips.com/sqlservertip/2442/move-data-between-sql-server-database-filegroups/

正如其他朋友已经说过的那样,接受marc_s接受的回答是截图给出了另一种使用SSMS GUI的方法。

请注意,您可以轻松地从存储选项卡中的index属性移动到另一个文件组 enter image description here

答案 4 :(得分:2)

请注意,重新创建聚簇索引只会移动“原始”列,例如int, bit, datetime等。

要移动varchar(max), varbinary和其他“ blob”列,您必须重新创建表。幸运的是,有一种方法可以在SSMS中半自动执行此操作-通过在表“设计”窗口中更改“文本文件组”,然后保存更改。

如果您需要更多详细信息,我在这里写过博客:https://www.jitbit.com/alexblog/153-moving-sql-table-textimage-to-a-new-filegroup/

答案 5 :(得分:1)

如何将表移动到另一个文件组?

注意:将表移动到另一个文件组仅适用于Enterprise Edition。

  

第1步:

     

检查所驻留的文件组表:

-- Query to check the tables and their current filegroup:

SELECT    tbl.name AS [Table Name], 
          CASE WHEN dsidx.type='FG' THEN dsidx.name ELSE '(Partitioned)' END AS [File Group] 
FROM      sys.tables AS tbl 
JOIN      sys.indexes AS idx 
ON        idx.object_id = tbl.object_id 
AND       idx.index_id <= 1 
LEFT JOIN sys.data_spaces AS dsidx 
ON        dsidx.data_space_id = idx.data_space_id 
ORDER BY  [File Group], [Table Name] 
  

第2步:

     

将现有的表/表移动到新的文件组

如果要将表移动到的文件组尚不存在,请创建辅助文件组,然后移动表。

要将表移动到其他文件组,需要将表的聚簇索引移动到新文件组。聚簇索引的叶级实际上包含表数据。因此,可以使用DROP_EXISTING子句在单个语句中完成移动聚簇索引,如下所示:

CREATE UNIQUE CLUSTERED INDEX [Index_Name] ON [SchemaName].[TableName]
(
    [ClusteredIndexKeyFields]
)WITH (DROP_EXISTING = ON, ONLINE = ON) ON [FilegroupName]
GO
  

第3步:

     

将剩余的非群集索引移动到辅助文件组

您必须使用以下语法手动移动非聚集索引:

--1st check the index information using the following sp
sp_helpindex [YourTableName]


--Now by using the following query you can move the remaining indexes to secondary filegroup
CREATE NONCLUSTERED INDEX [Index_Name] ON [SchemaName].[TableName]
(
    [IndexKeyFields]
)WITH (DROP_EXISTING = ON, ONLINE = ON) ON [FilegroupName]
GO

将堆移动到另一个文件组:

据我所知,将Heap移动到另一个文件组的唯一方法是在新文件组上临时添加聚簇索引,然后删除它(如果需要)。

答案 6 :(得分:0)

我认为这些步骤非常简单,可以直接将任何表格移动到不同的文件组(通过Management Studio):

  • 只需更改即可将所有非聚集索引移动到新文件组 每个索引的FileGroup属性

  • 将群集索引更改为非群集并简单地更改其文件组(如上一步所述)

  • 通过此命令(或通过IDE)添加带有“新文件组”的新临时群集索引:

       CREATE CLUSTERED INDEX [PK_temp]
    ON YOURTABLE([Id])
      ON NEWFILEGROUP
    

    (上述命令导致将所有数据移动到新文件组)

  • 删除上述临时PK(当它完美地完成工作时!)

  • 将主群集索引再次更改为群集索引(再次通过IDE)

上述步骤的好处是不需要删除现有的FK关系。此外,使用IDE可防止在错误条件下丢失数据。

注意:确保没有为您的FileGroup启用磁盘配额或将其设置为ocrrectly。否则你会得到“filegroup is full”异常!

答案 7 :(得分:0)

CREATE CLUSTERED INDEX IXC_Products_Product_id
ON dbo.Products(Product_id)
WITH (DROP_EXISTING = ON) ON MyNewFileGroup

答案 8 :(得分:0)

在SSMS中,展开Tables,展开你要移动的表,展开Indexes,右键点击聚集索引,点击“Script Index as”->“Drop and Create to”

这将打开一个带有脚本的查询窗口,以删除聚集索引并创建一个与原始索引相同规格的新索引。

在查询窗口中,在“ALTER TABLE <> ADD CONSTRAINT”语句中,在语句末尾的“ON”关键字后更改文件组的名称,例如如果表在 PRIMARY 文件组上,并且您想移动到名为“SECONDARY”的文件组,请将“ON [PRIMARY]”更改为“ON [SECONDARY]”。如果您希望表格保持在线,也可以将“ONLINE = OFF”更改为“ONLINE = ON”。

执行脚本,它将删除原始文件并在给定的文件组中创建一个新的。