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

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

简介

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

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

–******************
–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中变为了空。

image

如果需要切换回来执行

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)运行工作负载来提供是否分区的建议。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/119737.html原文链接:https://javaforall.net

(0)
上一篇 2021年11月25日 下午1:00
下一篇 2021年11月26日 上午6:00


相关推荐

  • 一般线性模型(general linear model,GLM)

    一般线性模型(general linear model,GLM)文章目录广义线性模型与一般线性模型 前言 reference 广义线性模型与一般线性模型 前言 广义线性模型 generalizedl GLM 是对普通线性回归的一种灵活的推广 它允许有误差分布模型且非正态分布的响应变量 广义线性模型通过允许线性模型通过连接函数 linkfunction 与响应变量的相关以及允许每个测量的方差的大小作为其预测值的函数来推广线性回归 公式为 E Y g 1 X E Y g 1 X beta E Y g 1 X 其中 E y 为

    2026年3月16日
    2
  • PHPWAMP集成环境Zend组件的相关介绍,环境默认的PHP运行模式「建议收藏」

    PHPWAMP集成环境Zend组件的相关介绍,环境默认的PHP运行模式「建议收藏」PHPWAMP集成环境Zend组件的相关介绍,站点管理默认已经全部安装Zend解密

    2022年6月28日
    27
  • php+将json转字符串,php实现json转字符串的方法

    php+将json转字符串,php实现json转字符串的方法php 实现 json 转字符串的方法发布时间 2020 11 0909 48 42 来源 亿速云阅读 68 作者 小新这篇文章主要介绍了 php 实现 json 转字符串的方法 具有一定借鉴价值 需要的朋友可以参考下 希望大家阅读完这篇文章后大有收获 下面让小编带着大家一起了解一下 在 php 中可以使用 json decode 函数实现 json 转字符串 该函数的作用就是对 JSON 格式的字符串进行解码 其使用语法是 j

    2026年3月19日
    3
  • 阿里云 mysql tps_MySQL_tps

    阿里云 mysql tps_MySQL_tpsTPS TransactionP 一个系统的吞度量 承压能力 与 request 对 CPU 的消耗 外部接口 IO 等等紧密关联 单个 reqeust 对 CPU 消耗越高 外部系统接口 IO 影响速度越慢 系统吞吐能力越低 反之越高 MySQL tps 每秒钟系统能够处理的交易或事务的数量 它是衡量系统处理能力的重要指标 TPS 是 LoadRunner 中重要的性能参数指标 usr bin

    2026年3月26日
    2
  • LRU和LFU的区别

    LRU和LFU的区别对于 web 开发而言 缓存必不可少 也是提高性能最常用的方式 无论是浏览器缓存 如果是 chrome 浏览器 可以通过 chrome cache 查看 还是服务端的缓存 通过 memcached 或者 redis 等内存数据库 缓存不仅可以加速用户的访问 同时也可以降低服务器的负载和压力 那么 了解常见的缓存淘汰算法的策略和原理就显得特别重要 常见的缓存算法 LRU Leastrecentl

    2026年3月19日
    1
  • Android报错误:Error inflating class ImageView

    Android报错误:Error inflating class ImageView在高版本手机运行的程序的时候没有问题 但是在 Android5 0 以下的时候就出现这个错误了 问题出现在 ImageView 设置背景图片是 drawable 的 系统自动放在了 drawable v24 中 导致在低分辨率手机上无法找到图片而报错 解决办法 将 drawable 改成 mipmap 就可以了 本人菜鸟一个 有什么不对的地方希望大家指出评论 大神勿喷 希望大家一起学习进步

    2026年3月17日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号