简介

之前一篇简单的介绍了语法和一些基本的概念,隔了一段时间,觉得有必要细致的通过实例来总结一下这部分内容。如之前所说,分区就是讲大型的对象(表)分成更小的块来管理,基本单位是行。这也就产生了很大优势, 比如在数据库维护备份还原操作的时候,比如在大量用户访问能导致死锁的时候等等。

接下来我们通过大量实例从分区到展示分区的效果以及一些实际案例来提高对这部分知识的理解。

--****************** --1.创建分区函数             --******************

--Create the partition function: dailyPF            DECLARE @StartDay DATE=DATEADD(dd,-3,CAST(SYSDATETIME() AS DATE));             CREATE PARTITION FUNCTION DailyPF (DATETIME2(0))                 AS RANGE RIGHT FOR VALUES                 (@StartDay, DATEADD(dd,1,@StartDay), DATEADD(dd,2,@StartDay),          DATEADD(dd,3,@StartDay), DATEADD(dd,4,@StartDay) );             GO

范围分区函数指定范围的边界,left和right关键字指定当数据库引擎按照剩余从左到右对区间值进行排序是,边界值属于那一边,默认为left。分区范围不能有间隔。

--******************            --2. 创建文件组

--******************

ALTER DATABASE PartitionThis ADD FILEGROUP DailyFG1            GO             ALTER DATABASE PartitionThis ADD FILEGROUP DailyFG2             GO             ALTER DATABASE PartitionThis ADD FILEGROUP DailyFG3             GO             ALTER DATABASE PartitionThis ADD FILEGROUP DailyFG4             GO             ALTER DATABASE PartitionThis ADD FILEGROUP DailyFG5             GO             ALTER DATABASE PartitionThis ADD FILEGROUP DailyFG6             GO

这里我们建立6个文件组,同时也可以为文件组创建文件,

接下来我为文件组创建分区方案:

--******************           --3. 创建分区架构            --******************

--           CREATE PARTITION SCHEME DailyPS                 AS PARTITION DailyPF                TO (DailyFG1, DailyFG2, DailyFG3, DailyFG4, DailyFG5, DailyFG6);

--******************            --4. 在分区架构上建表            --******************

if OBJECT_ID('OrdersDaily','U') is null            CREATE TABLE OrdersDaily (                OrderDate DATETIME2(0) NOT NULL,                OrderId int IDENTITY NOT NULL,                OrderName nvarchar(256) NOT NULL            ) on DailyPS(OrderDate)            GO

这里我们将分区函数映射到单个文件组里面,调用我们之前建立的分区函数即可。然后接着创建表在分区文件上,同时应用分区函数在

OrderDate时间上。这里我们还需要插入一部分测试数据便于观察,同时创建一个架构便于查询分区

--*******************************           --创建架构            --*******************************

--Create a schema for "partition helper" objects           CREATE SCHEMA [ph] AUTHORIZATION dbo;            GO

--插入测试数据           INSERT OrdersDaily(OrderDate, OrderName)             SELECT DATEADD(ss, t.N, DATEADD(dd,-3,CAST(CAST(SYSDATETIME() AS DATE) AS DATETIME2(0)))) AS OrderDate,                CASE WHEN t.N % 3 = 0 THEN 'Robot' WHEN t.N % 4 = 0 THEN 'Badger'  ELSE 'Pen' END AS OrderName            FROM ph.tally AS t--tally是一个1到10万自增长的表,只有一个字段 N

WHERE N < = 1000;

INSERT OrdersDaily(OrderDate, OrderName)            SELECT DATEADD(ss, t.N, DATEADD(dd,-2,CAST(CAST(SYSDATETIME() AS DATE) AS DATETIME2(0)))) AS OrderDate,                CASE WHEN t.N % 3 = 0 THEN 'Flying Monkey' WHEN t.N % 4 = 0 THEN 'Junebug'  ELSE 'Pen' END AS OrderName            FROM ph.tally AS t            WHERE N < = 2000;

INSERT OrdersDaily(OrderDate, OrderName)             SELECT DATEADD(ss, t.N, DATEADD(dd,-1,CAST(CAST(SYSDATETIME() AS DATE) AS DATETIME2(0)))) AS OrderDate,                CASE WHEN t.N % 2 = 0 THEN 'Turtle' WHEN t.N % 5 = 0 THEN 'Eraser'  ELSE 'Pen' END AS OrderName            FROM ph.tally AS t            WHERE N < = 3000;

INSERT OrdersDaily(OrderDate, OrderName)             SELECT DATEADD(ss, t.N, CAST(CAST(SYSDATETIME() AS DATE) AS DATETIME2(0))) AS OrderDate,                CASE WHEN t.N % 3 = 0 THEN 'Lasso' WHEN t.N % 2 = 0 THEN 'Cattle Prod'  ELSE 'Pen' END AS OrderName            FROM ph.tally AS t            WHERE N < = 4000;            GO

随即在创建相关的索引

--******************           --7. 创建索引            --******************            --添加聚集索引            ALTER TABLE OrdersDaily            ADD CONSTRAINT PKOrdersDaily                PRIMARY KEY CLUSTERED(OrderDate,OrderId)            GO

--对齐索引            --            CREATE NONCLUSTERED INDEX NCOrderIdOrdersDaily                 ON OrdersDaily(OrderId)            GO

--非对齐索引            CREATE NONCLUSTERED INDEX NCOrderNameOrdersDailyNonAligned                 ON OrdersDaily(OrderName) ON [PRIMARY]            GO

此时建立分区文件数据等条件后,我们可以看一下相应的文件及数据的情况,可以同过如下DMV来查看

SELECT  SCHEMA_NAME(so.schema_id) AS schema_name ,                   OBJECT_NAME(p.object_id) AS object_name ,                    p.partition_number ,                    p.data_compression_desc ,                    dbps.row_count ,                    dbps.reserved_page_count * 8 / 1024. AS reserved_mb ,                    si.index_id ,                    CASE WHEN si.index_id = 0 THEN '(heap!)'                            ELSE si.name                    END AS index_name ,                    si.is_unique ,                    si.data_space_id ,                    mappedto.name AS mapped_to_name ,                    mappedto.type_desc AS mapped_to_type_desc ,                    partitionds.name AS partition_filegroup ,                    pf.name AS pf_name ,                    pf.type_desc AS pf_type_desc ,                    pf.fanout AS pf_fanout ,                    pf.boundary_value_on_right ,                    ps.name AS partition_scheme_name ,                    rv.value AS range_value            FROM    sys.partitions p            JOIN    sys.objects so                    ON p.object_id = so.object_id                        AND so.is_ms_shipped = 0            LEFT JOIN sys.dm_db_partition_stats AS dbps                    ON p.object_id = dbps.object_id                        AND p.partition_id = dbps.partition_id            JOIN    sys.indexes si                    ON p.object_id = si.object_id                        AND p.index_id = si.index_id            LEFT JOIN sys.data_spaces mappedto                    ON si.data_space_id = mappedto.data_space_id            LEFT JOIN sys.destination_data_spaces dds                    ON si.data_space_id = dds.partition_scheme_id                        AND p.partition_number = dds.destination_id            LEFT JOIN sys.data_spaces partitionds                    ON dds.data_space_id = partitionds.data_space_id            LEFT JOIN sys.partition_schemes AS ps                    ON dds.partition_scheme_id = ps.data_space_id            LEFT JOIN sys.partition_functions AS pf                    ON ps.function_id = pf.function_id            LEFT JOIN sys.partition_range_values AS rv                    ON pf.function_id = rv.function_id                        AND dds.destination_id = CASE pf.boundary_value_on_right                                                    WHEN 0 THEN rv.boundary_id                                                    ELSE rv.boundary_id + 1                                                END

查询结果如图:

可以发现按照日期的分布产生了不同文件组的数据插入到了不同的文件里面和索引里面了。

接下来我们通过分区切换来更好的理解分区的意义,首先要建立新的文件组(DailyF7)来切换分区,同时创建一个分区表OrdersDailyLoad,并向这个表里面插入5000条数据创建索引等以上的操作单独对此表进行一遍重复操作,来实现对新分区的新标的对齐。注意5000条数据一定要在指定范围内,比如使用check约束使数据在11.30-12.1日内的数据。

代码:

在切换之前我们一定要禁用或者删除掉这个分区的对其的索引   ALTER INDEX NCOrderNameOrdersDailyNonAligned ON OrdersDaily DISABLE;    GO    ALTER TABLE OrdersDailyLoad    SWITCH TO OrdersDaily PARTITION 6;    GO

如图,分区切换后文件组6中变为了5000条数据,而7中变为了空。

如果需要切换回来执行

ALTER TABLE PARTITION 6  SWITCH TO OrdersDaily OrdersDailyLoad ;  GO

如果需要合并分区

ALTER PARTITION FUNCTION DailyPF ()           MERGE RANGE (‘2015-11-27 00:00:00.000’)

结果:此界点两个分区将合并为一个

总结:

通过以上代码和实例的展示,我们能了解如何使用分区。同时我们要知道分区的意义。但是要知道分区也是一把双刃剑,它可以看做是一个性能选项、管理选项、可扩展工具,在提高数据查询、维护性能的同时也对数据库的备份还原策略、索引的维护、并发性以及变分区锁等有副作用,所以具体是否选用表分区要根据实际情况来判断,然后推荐一个工具(DataBase Tuning Adcisor)运行工作负载来提供是否分区的建议。

优化SQLServer--表和索引的分区(二)的更多相关文章

  1. ORACLE表、索引和分区详解

    ORACLE表.索引和分区 一.数据库表 每种类型的表都有不同的特性,分别应用与不同的领域 堆组织表 聚簇表(共三种) 索引组织表 嵌套表 临时表 外部表和对象表 1.行迁移 建表过程中可以指定以下两 ...

  2. 优化SQLServer——表和分区索引

    概念: 简单地说,分区是将大型的对象(如表)分成更小的且易于管理的小块.分区的基本单位是行,需要注意的是与分区视图不同的地方时,分区必须位于同一个数据库内. 分区的原因:            对于非 ...

  3. MySQL数据库性能优化:表、索引、SQL等

    一.MySQL 数据库性能优化之SQL优化 注:这篇文章是以 MySQL 为背景,很多内容同时适用于其他关系型数据库,需要有一些索引知识为基础 优化目标 减少 IO 次数IO永远是数据库最容易瓶颈的地 ...

  4. 【HICP Gauss】数据库 数据库管理(数据库对象 表空间 索引 序列 分区 视图)-8

    什么是数据库对象 数据库对象包括 表 索引 分区 视图 序列 同义词 数据库支持对象存储过程 自定义函数 触发器 表空间 高级包 表 数据库中的数据结构 存储数据以及描述数据间的关系 表由行和列组成 ...

  5. sp_rename sqlserver 表 列 索引 类型重命名

    --[语法] sp_rename [ @objname = ] 'object_name' , [ @newname = ] 'new_name' [ , [ @objtype = ] 'object ...

  6. 优化SQLServer——表和分区索引(二)

    简介     之前一篇简单的介绍了语法和一些基本的概念,隔了一段时间,觉得有必要细致的通过实例来总结一下这部分内容.如之前所说,分区就是讲大型的对象(表)分成更小的块来管理,基本单位是行.这也就产生了 ...

  7. Oracle初始化数据库表空间、用户、表(索引、分区)等

    [oracle@bogon orcl]$ sqlplus sys/sys as sysdba SQL*Plus: Release 11.2.0.1.0 Production on Wed Oct 8 ...

  8. SQL Server查询性能优化——堆表、碎片与索引(二)

    本文是对 SQL Server查询性能优化——堆表.碎片与索引(一)的一些总结.  第一:先对 SQL Server查询性能优化——堆表.碎片与索引(一)中的例一的SET STATISTICS IO之 ...

  9. Phoenix表和索引分区优化方法

    Phoenix表和索引分区,基本优化方法 优化方法 1. SALT_BUCKETS RowKey SALT_BUCKETS 分区 2. Pre-split RowKey分区 3. 分列族 4. 使用压 ...

随机推荐

  1. 解决VMWARE NAT SERVICE服务无法启动或服务消失的问题

    解决VMWARE NAT SERVICE服务无法启动或服务消失的问题 2016-02-02 11:18 2012人阅读 评论(2) 收藏 举报  分类: 网络通信(3)  今日使用VMware中的Wi ...

  2. 使用google 语言 api 来实现整个网站的翻译

    ---恢复内容开始--- 使用google 语言 api 来实现整个网站的翻译,这时我们可以利用免费的google api来做处理来实现多语言的功能. 放在 HTML 文件中 <div id=& ...

  3. Android-环境问题

    大家都知道 Android Studio 是 Goole 的亲儿子,但,亲儿子毕竟也是刚出生2年不到,身上大毛病没有,小毛病大一堆,这篇博文就来总结一下常见的Android Studio 的设置,使用 ...

  4. thinkphp - 复合查询(or、and 联合使用的方法)

    条件:查询今天内邮箱和QQ其中一项都不为空的有效数据的查询 释义:(or 条件)email  不为空 或者 qq_no 不为空    (and 条件) is_deleted 为0 并且 create_ ...

  5. IOC框架

    一. IOC理论的背景 我们都知道,在采用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,所有的对象通过彼此的合作,最终实现系统的业务逻辑. 图1:软件系统中耦合的对象 如果我们打开机 ...

  6. 事件EVENT与waitforsingleobject的使用

    事件event与waitforsingleobject的配合使用,能够解决很多同步问题,也可以在数据达到某个状态时启动另一个线程的执行,如报警. event的几个函数: 1.CreateEvent和O ...

  7. 批量Shink所有日志或数据文件

    近期,因磁盘空间问题,当执行常规性维护如碎片整理等后会报磁盘空间不足警告,因条件又无法及时添加磁盘空间,这时候不得不对LOG文件做收缩,如果遇到库比较多的实例上,一个一个来却是比较麻烦,可通过如下SQ ...

  8. 读书笔记--SQL必知必会14--组合查询

    14.1 组合查询 复合查询(compound query)或并(union),SQL允许执行多个查询(多条SELECT语句),并将结果作为一个查询结果集返回. 应用场景: 在一个查询中从不同的表返回 ...

  9. 分布式系统理论基础 - 一致性、2PC和3PC

    引言 狭义的分布式系统指由网络连接的计算机系统,每个节点独立地承担计算或存储任务,节点间通过网络协同工作.广义的分布式系统是一个相对的概念,正如Leslie Lamport所说[1]: What is ...

  10. 没有神话,聊聊decimal的“障眼法”

    0x00 前言 在上一篇文章<妥协与取舍,解构C#中的小数运算>的留言区域有很多朋友都不约而同的说道了C#中的decimal类型.事实上之前的那篇文章的立意主要在于聊聊使用二进制的计算机是 ...