一、前言

  在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

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

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

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

  2. SQL Server 解读【已分区索引的特殊指导原则】(2)- 唯一索引分区

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

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

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

  4. 千万级SQL Server数据库表分区的实现

    千万级SQL Server数据库表分区的实现 2010-09-10 13:37 佚名 数据库 字号:T | T 一般在千万级的数据压力下,分区是一种比较好的提升性能方法.本文将介绍SQL Server ...

  5. SQL Server 批量主分区备份(Multiple Jobs)

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 案例分析(Case) 方案一(Solution One) 方案二(Solution Two) ...

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

    一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 案例分析(Case) 实现代码(SQL Codes) 主分区完整.差异还原(Primary B ...

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

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

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

    前言 本篇继续玩转模块的内容,关于索引在SQL Server的位置无须多言,本篇将分析如何利用Hint引导语句充分利用索引进行运行,同样,还是希望扎实掌握前面一系列的内容,才进入本模块的内容分析. 闲 ...

  9. SQL Server 创建表分区

    原文:SQL Server 创建表分区 先准备测试表 CREATE TABLE [dbo].[Employee] ( EmployeeNo ,) PRIMARY KEY, EmployeeName ) ...

随机推荐

  1. spring源码解析——spring源码导入eclipse

    一.前言     众所周知,spring的强大之处.几乎所有的企业级开发中,都使用了spring了.在日常的开发中,我们是否只知道spring的配置,以及简单的使用场景.对其实现的代码没有进行深入的了 ...

  2. SSDB 主从配置

    环境 Master/Slave     系统 IP SSDB版本 Master     CentOS6.7         10.10.3.211         ssdb-1.8.0     Sla ...

  3. Canvas 最佳实践(性能篇)

    Canvas 想必前端同学们都不陌生,它是 HTML5 新增的「画布」元素,允许我们使用 JavaScript 来绘制图形.目前,所有的主流浏览器都支持 Canvas. Canvas 最常见的用途是渲 ...

  4. 基于shell脚本比较数字加减乘除

    让用户输入两个数来比较他们的大小 先用touch命令新建一个2.sh文件 在用vi进入i进入编辑状态 输入 保存后检查

  5. MySQL中EXPLAIN命令详解

    explain显示了mysql如何使用索引来处理select语句以及连接表.可以帮助选择更好的索引和写出更优化的查询语句. 使用方法,在select语句前加上explain就可以了: 如: expla ...

  6. jsfl脚本设置导出AS链接名遇到的奇怪问题

    今天写jsfl脚本发现一个奇怪的问题,脚本用于对库对象设置AS链接名,代码如下: var item = fl.getDocumentDOM().library.items[0];var exportN ...

  7. <十四>JDBC_c3p0数据库连接池

    配置文件:c3p0-config.xml <!-- Hibernate官方推荐使用的数据库连接池即c3p0;dbcp是Tomcat在数据源中使用 --><c3p0-config> ...

  8. js,css控制网页内容不让选中和复制

    ---恢复内容开始--- JS, CSS控制网页内容不让选择和复制 CSS 控制: <style> body{ -moz-user-select:none;//针对火狐浏览器,谷歌则-we ...

  9. python Django session/cookie

    一, Cookie #cookie # def cook1(request): # print(request.COOKIES) # 查看cooke # # print(request.get_sig ...

  10. CentOS6.5安装Tomcat

    安装说明 安装环境:CentOS-6.4 安装方式:源码安装 软件:apache-tomcat-7.0.56.tar.gz 下载地址:http://tomcat.apache.org/download ...