一、前言

  在MSDN上看到一篇关于SQL Server 表分区的文档:已分区索引的特殊指导原则,如果你对表分区没有实战经验的话是比较难理解文档里面描述的意思。这里我就里面的一些概念进行讲解,方便大家的交流。

(Figure0:索引与基表对齐)

二、解读

“索引要与其基表对齐,并不需要与基表参与相同的命名分区函数。但是,索引和基表的分区函数在实质上必须相同,即:

1) 分区函数的参数具有相同的数据类型;

2) 分区函数定义了相同数目的分区;

3) 分区函数为分区定义了相同的边界值。”

下面我们进行测试:

--1.创建文件组
ALTER DATABASE [Test]
ADD FILEGROUP [FG_TestUnique_Id_01]ALTER DATABASE [Test]
ADD FILEGROUP [FG_TestUnique_Id_02]ALTER DATABASE [Test]
ADD FILEGROUP [FG_TestUnique_Id_03]--2.创建文件
ALTER DATABASE [Test]
ADD FILE
(NAME = N'FG_TestUnique_Id_01_data',FILENAME = N'E:\DataBase\FG_TestUnique_Id_01_data.ndf',SIZE = 1MB, FILEGROWTH = 1MB )
TO FILEGROUP [FG_TestUnique_Id_01];ALTER DATABASE [Test]
ADD FILE
(NAME = N'FG_TestUnique_Id_02_data',FILENAME = N'E:\DataBase\FG_TestUnique_Id_02_data.ndf',SIZE = 1MB, FILEGROWTH = 1MB )
TO FILEGROUP [FG_TestUnique_Id_02];ALTER DATABASE [Test]
ADD FILE
(NAME = N'FG_TestUnique_Id_03_data',FILENAME = N'E:\DataBase\FG_TestUnique_Id_03_data.ndf',SIZE = 1MB, FILEGROWTH = 1MB )
TO FILEGROUP [FG_TestUnique_Id_03];--3.创建分区函数
CREATE PARTITION FUNCTION
Fun_TestUnique_Id(INT) AS
RANGE RIGHT
FOR VALUES(10000000,20000000)--4.创建分区方案
CREATE PARTITION SCHEME
Sch_TestUnique_Id AS
PARTITION Fun_TestUnique_Id
TO([FG_TestUnique_Id_01],[FG_TestUnique_Id_02],[FG_TestUnique_Id_03])

上面的SQL脚本创建了分区函数:Fun_TestUnique_Id(INT)和分区方案:[Sch_TestUnique_Id]。下面我们创建类似的分区函数:Fun_TestUnique_SiteId(INT)和分区方案:[Sch_TestUnique_SiteId]。这两个函数完全符合上面提到的3个条件:

1) 分区函数的参数具有相同的数据类型;(都是Int类型)

2) 分区函数定义了相同数目的分区;(都是3个分区)

3) 分区函数为分区定义了相同的边界值。”(边界值都是10000000,20000000)

--1.创建文件组
ALTER DATABASE [Test]
ADD FILEGROUP [FG_TestUnique_SiteId_01]ALTER DATABASE [Test]
ADD FILEGROUP [FG_TestUnique_SiteId_02]ALTER DATABASE [Test]
ADD FILEGROUP [FG_TestUnique_SiteId_03]--2.创建文件
ALTER DATABASE [Test]
ADD FILE
(NAME = N'FG_TestUnique_SiteId_01_data',FILENAME = N'E:\DataBase\FG_TestUnique_SiteId_01_data.ndf',SIZE = 1MB, FILEGROWTH = 1MB )
TO FILEGROUP [FG_TestUnique_SiteId_01];ALTER DATABASE [Test]
ADD FILE
(NAME = N'FG_TestUnique_SiteId_02_data',FILENAME = N'E:\DataBase\FG_TestUnique_SiteId_02_data.ndf',SIZE = 1MB, FILEGROWTH = 1MB )
TO FILEGROUP [FG_TestUnique_SiteId_02];ALTER DATABASE [Test]
ADD FILE
(NAME = N'FG_TestUnique_SiteId_03_data',FILENAME = N'E:\DataBase\FG_TestUnique_SiteId_03_data.ndf',SIZE = 1MB, FILEGROWTH = 1MB )
TO FILEGROUP [FG_TestUnique_SiteId_03];--3.创建分区函数
CREATE PARTITION FUNCTION
Fun_TestUnique_SiteId(INT) AS
RANGE RIGHT
FOR VALUES(10000000,20000000)--4.创建分区方案
CREATE PARTITION SCHEME
Sch_TestUnique_SiteId AS
PARTITION Fun_TestUnique_SiteId
TO([FG_TestUnique_SiteId_01],[FG_TestUnique_SiteId_02],[FG_TestUnique_SiteId_03])

接下来创建一个以这个分区方案进行分区的表[TestUnique];这个表的聚集索引是创建在分区方案:[Sch_TestUnique_Id]上的。接着创建一个唯一索引:[IX_TestUnique_SiteIdUrl]是创建在分区方案[Sch_TestUnique_SiteId]上的。那么这个唯一索引跟基表是对齐的嘛?

--5.创建分区表
CREATE TABLE [dbo].[TestUnique]([Id] [int] IDENTITY(600000000,1) NOT FOR REPLICATION NOT NULL,[SiteId] [int] NULL,[Url] [nvarchar](420) NULL,[PublishOn] [datetime] NULL,[AddOn] [datetime] NULL,CONSTRAINT [PK_Archive] PRIMARY KEY CLUSTERED
([Id] ASC
)WITH (PAD_INDEX  = ON, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 100) ON [Sch_TestUnique_Id]([Id])
) ON [Sch_TestUnique_Id]([Id])
GO--6.创建唯一索引
CREATE NONCLUSTERED INDEX [IX_TestUnique_SiteIdUrl] ON [dbo].[TestUnique]
([SiteId] ASC,[Url] ASC
)WITH (SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, ONLINE = OFF) ON [Sch_TestUnique_SiteId]([SiteId])
GO

其实很明细,这个唯一索引[IX_TestUnique_SiteIdUrl]与基表是不对齐的,因为他们使用了不同的字段,一个是Id值,一个是SiteId值,很简单,因为Id为10000000的时候SiteId不一定也是10000000,所以他们没有办法对齐的;只要你进行一些切换分区就知道:

--插入测试数据
SET IDENTITY_INSERT [TestUnique] ON
INSERT INTO [TestDB].[dbo].[TestUnique] ([Id],[SiteId],[Url] ,[PublishOn] ,[AddOn])VALUES (10000010,10000009,'http://baidu.com',getdate(),getdate())
INSERT INTO [TestDB].[dbo].[TestUnique] ([Id],[SiteId],[Url] ,[PublishOn] ,[AddOn])VALUES (20000010,20000008,'http://baidu.com',getdate(),getdate())
SET IDENTITY_INSERT [TestUnique] OFF--创建切换分区临时表
CREATE TABLE [dbo].[Temp_TestUnique]([Id] [int] IDENTITY(600000000,1) NOT FOR REPLICATION NOT NULL,[SiteId] [int] NULL,[Url] [nvarchar](420) NULL,[PublishOn] [datetime] NULL,[AddOn] [datetime] NULL,CONSTRAINT [PK_TempArchive] PRIMARY KEY CLUSTERED
([Id] ASC
)WITH (PAD_INDEX  = ON, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 100) ON [Sch_TestUnique_Id]([Id])
) ON [Sch_TestUnique_Id]([Id])
GO
CREATE NONCLUSTERED INDEX [IX_TestUnique_SiteIdUrl] ON [dbo].[Temp_TestUnique]
([SiteId] ASC,[Url] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [Sch_TestUnique_SiteId]([SiteId])
GO--切换分区
ALTER TABLE [dbo].[TestUnique] SWITCH PARTITION 2 TO [dbo].[Temp_TestUnique] PARTITION 2

执行上面的切换分区SQL会报下面的错误:

消息4912,级别16,状态1,第2 行

'ALTER TABLE SWITCH' 语句失败。用于对表'Test.dbo.TestUnique' 进行分区的列集与用于对索引'IX_TestUnique_SiteIdUrl' 进行分区的列集不同。

[Sch_TestUnique_Id]([Id])与[Sch_TestUnique_SiteId]([SiteId])是属于不同的字段分区,如果换成[Sch_TestUnique_Id]([Id])与[Sch_TestUnique_SiteId]([Id]),虽然分区方案的名称不同,但是实质是一样的(参考上面3个条件的描述),这种情况我们也说索引与基表对齐了,可以进行切换分区了。下面是执行切换分区的效果图:

(Figure1:交换分区前)

(Figure2:交换分区后)

(Figure3:分区文件)

总结:使用不同的分区方案进行对齐的好处是让数据与索引分开存储,存储到不同的文件,但是它又是符合基表与索引是对齐,同时方便使用切换分区进行历史数据归档;

“先设计一个已分区表,然后为该表创建索引。执行此操作时,SQL Server 将使用与该表相同的分区方案和分区依据列自动对索引进行分区。因此,索引的分区方式实质上与表的分区方式相同。这将使索引与表“对齐”。

如果在创建时指定了不同的分区方案或单独的文件组来存储索引,则 SQL Server 不会将索引与表对齐。“

不同的分区方案并不是指不同的分区方案名,而是指不一样的分区方案结构。

三、参考文献

定义了索引视图时的分区切换

->使用分区切换高效传输数据

->已分区索引的特殊指导原则(唯一索引)

->设计分区以管理数据子集

Special Guidelines for Partitioned Indexes

转载于:https://www.cnblogs.com/gaizai/p/3214672.html

SQL Server 解读【已分区索引的特殊指导原则】(1)- 索引对齐相关推荐

  1. SQL Server 解读【已分区索引的特殊指导原则】(3) - 非聚集索引分区

    一.前言 在MSDN上看到一篇关于SQL Server 表分区的文档:已分区索引的特殊指导原则,如果你对表分区没有实战经验的话是比较难理解文档里面描述的意思.这里我就里面的一些概念进行讲解,方便大家的 ...

  2. SQL Server 当表分区遇上唯一约束(转载)

    一.前言 我已经在高兴对服务器创建了表分区并且获得良好性能和自动化管理分区切换的时候,某一天,开发人员告诉我,某表的两个字段的数据不唯一,需要为这两个字段创建唯一索引的时候,这一切就变得不完美了. 列 ...

  3. SQL Server 2005利用分区对海量数据的处理 [转自13590--北极燕鸥]

    超大型数据库的大小常常达到数百GB,有时甚至要用TB来计算.而单表的数据量往往会达到上亿的记录,并且记录数会随着时间而增长.这不但影响着数据库的运行效率,也增大数据库的维护难度.除了表的数据量外,对表 ...

  4. SQL Server调优系列进阶篇(如何维护数据库索引)

    前言 上一篇我们研究了如何利用索引在数据库里面调优,简要的介绍了索引的原理,更重要的分析了如何选择索引以及索引的利弊项,有兴趣的可以点击查看. 本篇延续上一篇的内容,继续分析索引这块,侧重索引项的日常 ...

  5. SQL Server 批量主分区备份(One Job)

    原文:SQL Server 批量主分区备份(One Job) 一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 案例分析(Case) 实现代码( ...

  6. SQL Server调优系列玩转篇三(利用索引提示(Hint)引导语句最大优化运行)

    SQL Server调优系列玩转篇三(利用索引提示(Hint)引导语句最大优化运行) 原文:SQL Server调优系列玩转篇三(利用索引提示(Hint)引导语句最大优化运行) 前言 本篇继续玩转模块 ...

  7. 【sql server】“已更新或删除的行值要么不能使该行成为唯一行,要么改变了多个行“ 解决方案

    [sql server]"已更新或删除的行值要么不能使该行成为唯一行,要么改变了多个行" 解决方案 参考文章: (1)[sql server]"已更新或删除的行值要么不能 ...

  8. 【SQL Server】已更新或删除的行值要么不能使该行成为唯一行,要么改变了多个行 问题解决

    [SQL Server]"已更新或删除的行值要么不能使该行成为唯一行,要么改变了多个行" 问题 问题阐述 在手动对表进行删除或修改操作时,可能会出现如下情况: 表结构及数据: 原因 ...

  9. SQL Server代理(已禁用代理XP) 出现的原因以及解决方法【通俗易懂,简洁明了】

    原因 打开SSMS连接数据库之后,你可能会看到了如下图所示[SQL Server 代理(已禁用代理 XP) ],那 为什么会这样呢 (」゜ロ゜)」? 因为你的SQL Server 的配置管理器中的SQ ...

最新文章

  1. COCO API的克隆 - http://cocodataset.org/
  2. Dom操作xml的常用方法
  3. 某公司的网络管理员职责
  4. 搭建FastDFS分布式文件方式一(Docker版本)
  5. XML 和 HTML中常用的转义字符
  6. 计时装饰器python_使用python装饰器制作计时函数
  7. 【Antlr】Antlr 资料 学习 网站
  8. UITableView(二)
  9. linux a7 a8,iOS12 A7/A8 固定Generator值 图文教程
  10. 世界主要国家货币名称列表整理[外贸免费工具]
  11. formidable词根词缀_托福词汇-重点词根词缀总结(二)
  12. 删除2345输入法和智能云输入法这两个狗屁玩意的注册表
  13. Python Decorator的来龙
  14. 行满秩矩阵为何变成增广矩阵还为满秩
  15. 图片与mat文件的转换
  16. 《现代控制理论》第四章
  17. linux insert最后一行,insert基础用法及进阶
  18. python全排列,递归
  19. 秋招校招,在线测评会不会通不过?
  20. 投资理财-老大爷的故事

热门文章

  1. opencvsharp_基于轮廓的形状匹配中匹配坐标与旋转角度
  2. yolov3为什么对大目标检测不好_基于改进Yolov3的目标检测的研究
  3. 12面魔方公式图解法_【高级篇】(三)三阶魔方CFOP高级玩法之——F2L
  4. 3d相册 html 代码_HTML5 3D立体图片相册
  5. c 清除 html标签,13.4. 去除HTML的标签tag:htmlRemoveTag
  6. labview波形图两个游标,LabVIEW数据可视化:使用波形图表控件逐点显示曲线的方法...
  7. ubuntu 能解析域名但ping不通_域名解析设置方法
  8. Guava之FluentIterable使用示例
  9. 【转载】一行代码加载网络图片到ImageView——Android Picasso
  10. 值得期待的.Net Micro Framework 3.0