SQL Server 2014新特性:分区索引和内存优化表

日期: 2013-10-20 来源:TechTarget中国 英文

编者按:本系列文章将详细介绍即将发布的SQL Server 2014中包含的重要特性。本文是第二篇,着重关注更新分区索引和内存优化表两个方面。第一篇请参考:http://www.searchdatabase.com.cn/showcontent_77166.htm SQL Server 2014中的更新分区索引 SQL Server 2014同样可以让重建分区列存储索引成为可能。例如,假设我们对ResellerSales表进行分区。

可以使用SSMS中的Create Partition Wizard (创建分区向导)。图1显示了Set Boundary Values对话框,你可以通过它进入向导的……

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

电子邮件地址不会被公开。 必填项已用*标注

敬请读者发表评论,本站保留删除与本文无关和不雅评论的权力。

编者按:本系列文章将详细介绍即将发布的SQL Server 2014中包含的重要特性。本文是第二篇,着重关注更新分区索引和内存优化表两个方面。第一篇请参考:http://www.searchdatabase.com.cn/showcontent_77166.htm

SQL Server 2014中的更新分区索引

SQL Server 2014同样可以让重建分区列存储索引成为可能。例如,假设我们对ResellerSales表进行分区。可以使用SSMS中的Create Partition Wizard (创建分区向导)。图1显示了Set Boundary Values对话框,你可以通过它进入向导的 Map Partitions界面。(我是基于OrderDate 字段创建分区的。)

图1:为Create Partition Wizard(创建分区向导)设置边界值

Set Boundary Values 对话框设置了值之后,回到Map Partitions 界面并为每个分区选择一个文件群组。就本例来说,我对所有分区使用PRIMARY 。然后点击Estimate storage 按钮来填充余下的网格。图2显示了系统上的最终结果。

图2:可以使用Create Partition Wizard(创建分区向导)来映射分区

不建议你以这种方式设置分区,不过以下例子就是建立在此配置上的。所以,此信息可能会对你有所帮助。

在创建了分区之后,你可以使用 sys.partitions 目录视图检索为ResellerSales 表所创建分区的相关信息,正如下面的SELECT 语句所示:

SELECT * FROM sys.partitions

WHERE object_id = OBJECT_ID('ResellerSales');

图3显示了此查询所返回的结果。注意它有五个分区,尽管只有前四个包含数据。还需注意每条记录中的data_compression_desc 字段显示压缩类型为COLUMNSTORE,这正是我们所想要看到的。

图3:可以查看表分区的sys.partitions 目录视图。

在SQL Server 2014中,我们可以使用一条单一的T-SQL语句来要么重建所有的分区集群列存储索引,要么重建个别索引。要更新所有的分区,可以再次使用 ALTER INDEX 语句。只是这次,我们会更改REBUILD 语句以包含PARTITION选项,正如下例所示:

ALTER INDEX ix_clustered

ON ResellerSales

REBUILD PARTITION = ALL;

我们已经将PARTITION 选项设置为ALL。但是,如果想要更新单个分区,需要将选项设置为特定的数字。(可以使用sys.partitions 目录视图来检索分区号。)例如,以下的ALTER INDEX 语句就是更新分区2:

ALTER INDEX ix_clustered

ON ResellerSales

REBUILD PARTITION = 2;

在一个集群列存储索引中能够很方便地重建个别分区,不过不能执行在线更新。换句话说就是,在索引重建操作期间,底层表中的数据是无法进行查询的。

然而,这并不适用于SQL Server 2014中所有的分区索引。例如,假设我们使用一个SELECT…INTO 语句来创建ResellerSales2 表:

SELECT *

INTO ResellerSales2

FROM FactResellerSales;

此语句添加了60855条记录到新表中。下面就如同对ResellerSales 表一样来对表进行分区。最后,使用以下CREATE CLUSTERED INDEX 语句来创建普通(非列存储)集群索引:

CREATE CLUSTERED INDEX ix_orderdate

ON ResellerSales2 (OrderDate);

当此表仍是在线状态的时候,现在可以更新与一个特定分区关联的索引。为此,我们需要再次更改ALTER INDEX 语句以包含一条WITH 语句,如下例中所示:

ALTER INDEX ix_orderdate

ON ResellerSales2

REBUILD PARTITION = 2

WITH (ONLINE = ON (WAIT_AT_LOW_PRIORITY

(MAX_DURATION = 10, ABORT_AFTER_WAIT = BLOCKERS)));

WITH 语句必须首先设置 ONLINE选项为ON 并在之后指定其他相关选项。在这种情况下,WAIT_AT_LOW_PRIORITY 选项会告知SQL Server等待建立索引,直到表中没有阻塞操作为止。MAX_DURATION 选项表明等待那些阻塞操作的所需分钟数。而ABORT_AFTER_WAIT 选项确定在等待之后要做什么。对于此例,已经指定了BLOCKERS,它告诉SQL Server去结束任何阻塞索引重建的事务。

创建内存优化表

SQL Server 2014中的内存引擎(代号为Hekaton)将OLTP提升到了新的高度。现在,存储引擎已整合进当前的数据库管理系统,而使用先进内存技术来支持大规模OLTP工作负载。尽管如此,要利用此新功能,数据库必须包含“内存优化”文件群组和表;即所配置的文件群组和表使用Hekaton技术。幸运的是,SQL Server 2014使这一过程变得非常简单直接。

要说明其工作原理,我们来创建一个名为TestHekaton的数据库,然后添加一个内存优化文件群组到此数据库,如下例中的T-SQL代码所示:

USE master;

GO

CREATE DATABASE TestHekaton;

GO

ALTER DATABASE TestHekaton

ADD FILEGROUP HekatonFG CONTAINS MEMORY_OPTIMIZED_DATA;

GO

注意ALTER DATABASE语句中的ADD FILEGROUP 语句包含文件群组的名称(HekatonFG)和关键字CONTAINS MEMORY_OPTIMIZED_DATA,它会指导SQL Server去创建支持内存OLTP引擎所必需的文件群组类型。要确认此文件群组已经创建,可以访问SSMS中数据库属性的Filegroups 界面,如下图4中所示。

图4:数据库属性中显示新的内存优化文件群组

下一步是添加一个文件到文件群组,可以通过执行第二个ALTER DATABASE语句来实现。下例是添加一个新文件到HekatonFG文件群组:

ALTER DATABASE TestHekaton

ADD FILE

(

NAME = 'HekatonFile',

FILENAME =

'C:Program FilesMicrosoft SQL ServerMSSQL11.SQLSRV2014CTP1MSSQLDATAHekatonFile'

)

TO FILEGROUP [HekatonFG];

GO

注意,在ADD FILE 语句中,我们只为文件路径和文件名提供了一个友好的名称。并且,在TOFILEGROUP 语句中,为新文件群组指定名称。然后可以去往数据库属性的 Files 界面来查看刚刚添加的文件,如图5中所示。

图5:数据库属性包含关于文件添加到文件群组的详细信息。

值得注意的是,可以使用数据库属性界面来直接添加文件群组和文件。这一切都取决于你偏向使用哪种方式。而使用脚本的好处在于可以保存并重新执行。

在为数据库设置了必需的文件群组和文件之后,就可以创建自己的内存优化表了。当在定义表的时候,会指定其“持久性”。一个内存优化表可以是持久的或非持久的。一个持久表是将数据存储在内存中,而且也保存在内存优化文件群组中。对于一个非持久表,数据是仅存储在内存中的,所以,如果系统崩溃或重启,数据就会丢失。在SQL Server 2014中默认用的是持久表,接下来我们来深入了解一下。

当定义一个持久内存优化表的时候,你还必须定义一个基于非集群哈希索引的主键。在一个哈希索引中,数据是通过一个内存散列表进行访问的,而非固定大小页。哈希索引是在内存优化表中唯一支持的索引类型。

除了在表定义中定义主键外,还必须将表配置为内存优化的,如下CREATE TABLE 语句所示:

USE TestHekaton;

GO

CREATE TABLE Reseller

(

ResellerID INT NOT NULL

PRIMARY KEY NONCLUSTERED HASH WITH (BUCKET_COUNT = 1024),

ResellerName NVARCHAR(50) NOT NULL,

ResellerType NVARCHAR(20) NOT NULL

) WITH (MEMORY_OPTIMIZED = ON, DURABILITY = SCHEMA_AND_DATA);

INSERT INTO Reseller

VALUES (1, 'A Bike Store', 'Value Added Reseller');

ResellerID 字段定义包含了定义为非集群哈希的主键。注意,必须包含一个WITH 语句来指定BUCKET_COUNT 的设置,它表明了在哈希索引中应该创建的bucket数量。(每个bucket是一个槽,可以用来存放一组键值对。)微软建议bucket的数量应是一到两倍于你所期望的表所要包含的唯一索引键的数量。

此表定义以第二个WITH 语句结束。这里你指定MEMORY_OPTIMIZED 选项为ON 以及DURABILITY 选项为SCHEMA_AND_DATA,此选项是针对持久表的。接着在表中插入一条记录,这样就可以进行尝试了。

这就是创建一个内存优化表的全部步骤,其他的一切都会发生在幕后。但是,要记住,SQL Server 2014对这些表有着很多限制。例如,它们不支持外键或约束检查,它们也不支持IDENTITY 字段或DML触发器。最为重要的是,内存耗尽会导致写活动停止。

另一方面,内存优化表支持本地编译存储过程,只要那些存储过程只引用内存优化表。在这种情况下,存储过程可以转化为本地代码,这样会执行更快且要比典型存储过程需要更少的内存。

除了只引用内存优化表,一个本地编译存储过程必须是模式绑定的并运行在一个特定执行内容内。另外,每个本地编译存储过程必须完全由一个原子块组成。

下面的CREATE PROCEDURE 语句定义了一个本地编译存储过程,它从前例中所创建的Reseller表中检索数据:

CREATE PROCEDURE GetResellerType

(

@id INT

)

WITH NATIVE_COMPILATION, SCHEMABINDING, EXECUTE AS OWNER

AS

BEGIN

ATOMIC WITH

(TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = 'us_english')

SELECT ResellerName, ResellerType

FROM dbo.Reseller

WHERE ResellerID = @id

END;

GO

在定义了参数之后,包含一个WITH 语句来指定NATIVE_COMPILATION 选项。注意,此语句还包含SCHEMABINDING 选项和EXECUTE AS 选项,以及指定了OWNER 作为执行环境。而WITH 语句负责实现本地编译存储过程的三大需求。

要解决原子块需求,可以在BEGIN 关键字后指定ATOMIC ,之后是另一个包含有事务隔离级别和语言的WITH 语句。对于访问内存优化表的事务,可以使用SNAPSHOTREPEATABLEREAD SERIALIZABLE 作为隔离级。而且,对于此语言必须使用一个可用的语言或语言别名。

这是在定义存储过程时所需要包含的全部内容。一旦创建,就可以通过执行EXECUTE 语句来对其加以测试,如下例中所示:

EXEC GetResellerType 1;

此语句会返回经销商的姓名和类型,在本例中分别是ABike StoreValue Added Reseller

相关推荐