SQL Server里在文件组间如何移动数据?
平常我不知道被问了几次这样的问题:“SQL Server里在文件组间如何移动数据?“你意识到这个问题:你只有一个主文件组的默认配置,后来围观了“SQL Server里的文件和文件组”后,你知道,有多个文件的自定义文件组会是个更好的主意。但你现在如何从主文件组里移动现有数据到新加的文件组?
这篇文章的目的是向你展示你如何在文件组间移动数据。首先我会谈下聚集和非聚集索引,然后我会谈下如何在堆表里移动数据。让我们开始吧!
移动聚集和非聚集索引
一般来说在你的表上通常应该有一个聚集索引。有了现存的聚集索引就很容易移动表数据(即聚集索引)到不同的文件组。下列代码我为表创建了一个简单的聚集和非聚集索引,并插入近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个索引(聚集索引和非聚集苏音)。
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的数据,你最终可以验证新分配在新加的文件组里发生,主文件组还是很小。搞定!
移动堆表
如果你想从堆表移动数据到自定义的文件组,这需要一点技巧。主要的问题是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
SQL Server里在文件组间如何移动数据?的更多相关文章
- SQL Server 在缺少文件组的情况下如何还原数据库
SQL Server 在缺少文件组的情况下如何还原数据库 一.背景 我有一个A库,由于a,b两张表的数据量比较大,所以对表进行分区:在把A库迁移到一个新的集群上去,我只备份了A库的主分区过去进行还原为 ...
- SQL Server里的文件和文件组
在今天的文章里,我想谈下SQL Server里非常重要的话题:SQL Server如何处理文件的文件组.当你用CREATE DATABASE命令创建一个简单的数据库时,SQL Server为你创建2个 ...
- sql server 里的文件和文件组使用
转自:https://www.cnblogs.com/woodytu/p/5821827.html 参考:https://www.sqlskills.com/blogs/paul/files-and- ...
- SQL Server架构 -- 数据库文件和文件组
在SQL SERVER中,数据库在硬盘上的存储方式和普通文件在Windows中的存储方式没有什么不同,也是在特定文件夹下创建不同的文件,然后经过文件存储系统去抓取数据信息.理解文件和文件组的概念可以帮 ...
- SQL Server中数据库文件的存放方式,文件和文件组
原文地址:http://www.cnblogs.com/CareySon/archive/2011/12/26/2301597.html SQL Server中数据库文件的存放方式,文件和文件组 ...
- SQL Server里的闩锁介绍
在今天的文章里我想谈下SQL Server使用的更高级的,轻量级的同步对象:闩锁(Latch).闩锁是SQL Server存储引擎使用轻量级同步对象,用来保护多线程访问内存内结构.文章的第1部分我会介 ...
- SQL Server里一些未公开的扩展存储过程
SQL Server里一些未公开的扩展存储过程 [转帖] 博客天地 www.inbaidu.com SQL Server里一些未公开的扩展存储过程 扩展存储过程(xp)是直接运行在SQL Server ...
- SQL Server里的INTERSECT
在今天的文章里,我想讨论下SQL Server里的INTERSECT设置操作.INTERSECT设置操作彼此交叉2个记录集,返回2个集里列值一样的记录.下图演示了这个概念. INTERSECT与INN ...
- SQL Server里的自旋锁介绍
在上一篇文章里我讨论了SQL Server里的闩锁.在文章的最后我给你简单介绍了下自旋锁(Spinlock).基于那个基础,今天我会继续讨论SQL Server中的自旋锁,还有给你展示下如何对它们进行 ...
随机推荐
- async & await 的前世今生(Updated)
async 和 await 出现在C# 5.0之后,给并行编程带来了不少的方便,特别是当在MVC中的Action也变成async之后,有点开始什么都是async的味道了.但是这也给我们编程埋下了一些隐 ...
- node中的cmd规范
你应该熟悉nodejs模块中的exports对象,你可以用它创建你的模块.例如:(假设这是rocker.js文件) exports.name = function() { console.log('M ...
- Dapper where Id in的解决方案
简单记一下,一会出去有点事情~ 我们一般写sql都是==>update NoteInfo set NDataStatus=@NDataStatus where NId in (@NIds) Da ...
- PHP数据类型之间的强制转换
1.实型数据强制转换为整型数据 $float1=2.7; $int1=(int)$float1; echo var_dump($int1),"<br>"; 输出: in ...
- 第一个移动前端开源项目-dailog
你还在为手机上没有忙碌光标而发愁吗?你还在抱怨弹出框组件要依赖zepto/jqery吗?你还在纠结是否要自己写一套还是去网上寻找成现成的UI组件吗?YouA为你轻松解决所有烦恼.YouA是我为移动前端 ...
- C#文件安全管理解析
在实际的项目开发中,我们经常需要使用到文件的I/O操作,主要包含对文件的增改删查等操作,这些基本的操作我们都是很熟悉,但是较少的人去考虑文件的安全和操作的管理等方面,例如文件的访问权限管理,文件数据的 ...
- 利用注册表在右键添加VS15的快捷方式打开文件夹
1.简介 最近安装VS15 Preview 5,本版本可以打开"文件夹" 是否可以向Visual Studio Code一样在文件夹或文件右键菜单添加"Open with ...
- c#比较两个数组的差异
将DataTable中某一列数据直接转换成数组进行比较,使用的Linq,要引用命名空间using System.Linq; string[] arrRate = dtRate.AsEnumerable ...
- 基于Vue2.0的单页面开发方案
2016的最后一天,多多少少都应该总结一下这一年的得失,哪里做的好,哪里需要改进,记一笔,或许将来会用到呢. 毕业差不多半年了,一直是一个人在负责公司项目的前端开发与维护,当时公司希望前后端分离,提高 ...
- MySQL加密
MySQL字段加密和解密 1.加密:aes_encrypt('admin','key') 解密:aes_decrypt(password,'key') 2.双向加密 通过密钥去加密,解密的时候的只有知 ...