概述

内存中OLTP(项目“Hekaton”)是一个全新的、完全集成到SQL Server的数据库引擎组件。 对OLTP工作负载访问中在内存中的数据进行了优化。内存中OLTP能够帮助OLTP工作负载实现显著的性能改善,并减少处理时间。表能被视为“内存优化”,提升内存中的OLTP功能。内存优化表是完全可事务的、并可以使用Transact-SQL进行访问。Transact-SQL存储过程可以编译成为机器码,从而进一步地提高内存优化表的性能。该引擎是专为高并发而设计的,并且阻塞是最小的。

术语

基于磁盘的表:

传统的表存储方式,具有以下主要属性:

· 映射到一个文件组,并且该文件组包含一个或多个文件。

· 每个文件划分为 8 个页区,每页的大小为 8K 字节。

· 可跨多个表共享一个区,但分配的页和表或索引之间存在一对一映射。 换言之,一个页面不能有来自两个或更多表或索引的行。

· 根据需要将数据移到内存(缓冲池)中,并且修改后的或新建的页面将以异步方式写入到主要生成随机 IO 的磁盘。

内存优化表:

内存优化表的存储具有以下主要属性:

· 所有内存优化表都映射到内存优化的文件组。 使用文件流文件组生成此文件组。

· 不存在任何页面,并且数据以行的形式保留。

· 对内存优化表进行的所有更改都通过追加到活动文件进行存储。 对文件进行的读取和写入操作是有顺序的。

· 按照先删除再插入的方式实现更新。 不会立即从存储中移除已删除的行。 依据内存优化表的持久性中所述的策略,已删除的行由称作 MERGE 的后台进程移除。

· 与基于磁盘的表不同,不对内存优化表的存储进行压缩。 在将压缩的(ROW 或 PAGE)基于磁盘的表迁移到内存优化表时,您将需要考虑大小的更改。

· 内存优化表可以是持久的或非持久的。 您只需为持久性内存优化表配置存储。

跨容器的事务:

是指同时参考内存优化表和基于磁盘的表的事务。

互操作性:

是指引用内存优化表的解释型的Transact-SQL。

可编译的Transact-SQL:

即传统的解释性Transact-SQL。当使用互操作时,内存优化表将会访问所有的Transact- SQL区域,但您不应该指望取得使用本地编译存储过程相同的性能。当运行即席查询时,互操作是合适的选择,或在应用程序迁移到内存中的OLTP之前使用。这种使用是最佳性能的关键程序迁移过程中的一个步骤。当您需要同时访问内存优化表和基于磁盘的表时,也可以使用可编译的Transact-SQL 。

Transact-SQL使用互操作访问内存优化表时,不支持的功能仅有以下几种:

· TRUNCATE TABLE;

· MERGE(内存优化表的目标);

· 动态和基于键值集的游标(这些都是自动降级到静态游标);

· 跨数据库中的查询;

· 跨数据库中的事务;

· 链接服务器;

· 锁定提示:TABLOCK、XLOCK、PAGLOCK等(NOLOCK支持);

· 隔离级别的提示READUNCOMMITTED、READCOMMITTED READCOMMITTEDLOCK;

· 内存优化的表类型和表中不只是由CTP1支持的变量。

本地编译的存储过程:

是指一种对象类型,这种类型被内存驻留OLTP所支持;内存驻留OLTP被编译为机器代码,并有可能进一步提高性能,甚至比只使用内存优化表更加优化。另一种替代方案是采用基于解释型的Transact-SQL存储过程,这是SQL Server中常用的、采用基础的编译的存储过程只能引用内存优化表。

包含内存中OLTP组件的SQL Server引擎

虽然内存驻留OLTP 与SQL Server关系型引擎集成,并能通过相同的接口访问,但是其内部的行为和性能却大相径庭。

无论调用本地编译的存储过程或者Transact-SQL,客户端应用程序采用与内存优化表或基于磁盘的表同样的方式连接到TDS处理器。您可以看到解释型的Transact-SQL能通过互操作能力访问内存优化表,但本地编译的存储过程只能访问内存优化表。

使用内存中OLTP

内存中OLTP引擎从2013年6月CTP版本开始,已经成为SQL Server 2014的一部分。内存中OLTP SQL Server的安装是SQL Server安装程序的一部分。内存中OLTP组件只能被安装在一个SQL Server 2014 64位版本中,而不与32位版本兼容。

准备:创建示例数据库

1
2
CREATE DATABASE imoltp
GO

第一步:设置数据库支持内存中OLTP

包含内存优化表的任何数据库至少需要有一个MEMORY_OPTIMIZED_DATA文件组。这些文件组用于存储数据和增量文件,这些文件被SQL Server用来恢复内存优化表。虽然创建MEMORY_OPTIMIZED_DATA文件组与创建常规FILESTREAM文件组的语法几乎是相同的,但是还是必须要指定CONTAINS MEMORY_OPTIMIZED_DATA这一选项。

下面通过两种方式来添加MEMORY_OPTIMIZED_DATA文件组和存放FILESTREAM文件的容器。

使用T-SQL实现:

1
2
3
ALTER DATABASE imoltp ADD FILEGROUP imoltp_mod CONTAINS MEMORY_OPTIMIZED_DATA
ALTER DATABASE imoltp ADD FILE (name='imoltp_mod1', filename='E:\SQL-DATA\imoltp_mod1'TO FILEGROUP imoltp_mod
GO

使用SSMS实现:

1. 在Object Explorer中, 展开数据库节点, 右键点击数据库,单击属性。   

2. 添加一个新的内存优化数据的文件组,点击文件组页面。在MEMORY OPTIMIZED DATA选项下,单击添加文件组并设置文件组的各项值。   

3. 在文件组中添加文件,点击general 页面。 在Database files下,点击添加并且输入文件的各项值。File type 设置为FILESTREAM Data。   

第二步:创建内存优化表

创建优化内存表的语法与创建基于磁盘的表的语法几乎相同,只有一些限制以及需要的扩展。指定表是内存优化表是用MEMORY_OPTIMIZED= ON语句实现的。内存优化表只可以有以下这些可支持的数据类型的列:

· 字节;

· 所有整数类型:tinyint、smallint、int、bigint;

· 所有money类型:money、smallmoney;

· 所有浮点类型:float、real;

· 所有日期/时间类型:datetime、smalldatetime、datetime2、date、time;

· 数字和浮点数类型;

· 所有非LOB字符类型:char(n)、varchar(n)、nchar(n)、nvarchar(n)、sysname;

· 非LOB二进制类型:binary(n)、varbinary(n);

· 独特的识别符。

请注意的是LOB数据类型是不可用的;不能有XML类型、CLR、或者max数据类型的列,并且所有行的长度都限制在8060个字节之内,而且没有行外数据。事实上,8060字节的限制是在表创建的时候执行的,所以不像基于磁盘的表,内存优化表不能创建两个varchar(5000)的列。

内存优化表可以通过两种DURABILITY值定义:SCHEMA_AND_DATA或SCHEMA_ONLY,前者是默认值。内存优化表由DURABILITY=SCHEMA_ONLY定义,这意味着表中数据的变化没有被记录下来,并且表中的数据并没有保存在磁盘上。但是,架构会被作为数据库元数据的一部分保存下来,所以在一个SQL Server重启的过程中恢复数据库之后,这样的空表是可用的。

如前所述,内存优化表必须至少有一个索引,但这一要求能通过索引自动创建来满足,从而支持主键约束。除了那些用schema_only选项所创建的表以外的其他表都必须有一个声明的主键。至少有一个索引必须声明支持一个主键约束。下面的示例显示了一个主键索引创建成为一个分区索引,其中的统计指标也必须被指定。

当创建内存优化表时,除已列的对数据类型的限制之外,只有少数的其他限制:

· 没有DML触发器;

· 没有FOREIGN KEY或CHECK约束;

· 没有IDENTITY列;

· 除了主键没有唯一索引;

· 最多8个索引,包括支持主键的索引。

此外,一旦一个表被创建后,架构是不可改变的。您将需要删除并重新创建表,而不是使用ALTER TABLE。此外,并没有具体的索引DDL命令(比如创建索引、修改索引、删除索引)。索引总是作为表创建的一部分而创建。

目前我们有两张表,‘ShoppingCart’和‘UserSession’。‘ShoppingCart’是一个持久化的表(默认值),这意味着表中的内容是存储在磁盘上的,不会因为服务器崩溃而丢失。‘UserSession’是一个非持久化的表(DURABILITY=SCHEMA_ONLY),这意味着表中内容仅存储在内存中,服务器重启即会丢失。

注:SQL 2014 内存优化的表支持非聚集哈希索引(hash index)和非聚集索引(rang index)。hash索引的Bucket_cout建议值是表中能找到的唯一索引键值个数的4到8倍。

下面通过两种方式来创建内存优化表。

使用T-SQL实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
USE imoltp
GO
-- durable table (持久化的表)
CREATE TABLE dbo.ShoppingCart (
ShoppingCartId int not null primary key nonclustered hash with
(bucket_count=2000000),
UserId int not null index ix_UserId nonclustered hash with (bucket_count=1000000),
CreatedDate datetime2 not null,
TotalPrice money
)
WITH (MEMORY_OPTIMIZED=ON)
GO
-- non-durable table (非持久化的表)
CREATE TABLE dbo.UserSession (
SessionId int not null primary key nonclustered hash with (bucket_count=400000),
UserId int not null,
CreatedDate datetime2 not null,
ShoppingCartId int,
index ix_UserId nonclustered hash (UserId) with (bucket_count=400000)
)
WITH(MEMORY_OPTIMIZED=ON, DURABILITY=SCHEMA_ONLY)
GO

使用SSMS实现:

1. 在Object Explorer,右键单击您数据库的Tables节点,点击new,然后点击Memory Optimized Table。然后可以看到创建内存优化表的模板。   

2. 替换模板中的参数,在query菜单中点击Specify Values for Template Parameters。快捷键是Ctrl-Shift-M。   

3. 执行完毕后,确认表已创建。   

第三步:加载数据

可以通过多种方式把数据加载到表中,包括 INSERT .. SELECT from一个已经存在的存储在磁盘上的表和BCP。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-- insert a few rows
INSERT dbo.UserSession VALUES (1,342,GETUTCDATE(),4)
INSERT dbo.UserSession VALUES (2,65,GETUTCDATE(),NULL)
INSERT dbo.UserSession VALUES (3,8798,GETUTCDATE(),1)
INSERT dbo.UserSession VALUES (4,80,GETUTCDATE(),NULL)
INSERT dbo.UserSession VALUES (5,4321,GETUTCDATE(),NULL)
INSERT dbo.UserSession VALUES (6,8578,GETUTCDATE(),NULL)
INSERT dbo.ShoppingCart VALUES (1,8798,GETUTCDATE(),NULL)
INSERT dbo.ShoppingCart VALUES (2,23,GETUTCDATE(),45.4)
INSERT dbo.ShoppingCart VALUES (3,80,GETUTCDATE(),NULL)
INSERT dbo.ShoppingCart VALUES (4,342,GETUTCDATE(),65.4)
GO
-- verify table contents
SELECT FROM dbo.UserSession
SELECT FROM dbo.ShoppingCart
GO

第四步:更新统计信息

内存优化的表不支持auto_update_statistics,因此统计信息需要手动进行更新。您可以使用UPDATE STATISTICS来更新单个表的统计信息或者sp_updatestats来更新数据库中的所有表的统计信息。

1
2
3
4
-- update statistics on memory optimized tables
UPDATE STATISTICS dbo.UserSession WITH FULLSCAN, NORECOMPUTE
UPDATE STATISTICS dbo.ShoppingCart WITH FULLSCAN, NORECOMPUTE
GO

第五步:执行查询

优化内存表可以以两种不同的方式访问:要么通过可编译的Transact-SQL互操作,或通过本地编译的存储过程。

现在您已经做好了执行查询的准备。因为查询需要访问内存优化的表,他们将会受益于不加锁的数据结构,从而提高了数据访问的效率。以下是一些例子:

1
2
3
4
5
6
7
8
9
10
11
12
-- in an explicit transaction, assign a cart to a session and update the total price.
-- note that the isolation level hint is required for memory-optimized tables with
-- SELECT/UPDATE/DELETEstatements in explicit transactions
BEGIN TRAN
UPDATE dbo.UserSession WITH (SNAPSHOT) SET ShoppingCartId=3 WHERE SessionId=4
UPDATE dbo.ShoppingCart WITH (SNAPSHOT) SET TotalPrice=65.84 WHERE ShoppingCartId=3
COMMIT
GO
-- verify table contents
SELECT FROM dbo.UserSession u JOIN dbo.ShoppingCart s on u.ShoppingCartId=s.ShoppingCartId
WHERE u.SessionId=4
GO

第六步:创建本地编译的存储过程

为了进一步优化内存优化表的访问以及优化您的业务逻辑的执行,您可以选择创建本地编译的存储过程。这些存储过程是使用Transact-SQL创建的,但并不支持完整的Transaction-SQL环境。具体细节可参考联机丛书。

以下是一个访问之前我们创建的表的本地编译的存储过程的例子。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
-- natively compiled stored procedure for assigning a shopping cart to a session
CREATE PROCEDURE dbo.usp_AssignCart @SessionId int
WITH NATIVE_COMPILATION, SCHEMABINDING, EXECUTE AS OWNER
AS
BEGIN ATOMIC
WITH (TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'us_english')
DECLARE @UserId int,
@ShoppingCartId int
SELECT @UserId=UserId, @ShoppingCartId=ShoppingCartId
FROM dbo.UserSession WHERE SessionId=@SessionId
IF @UserId IS NULL
THROW 51000, 'The session or shopping cart does not exist.', 1
UPDATE dbo.UserSession SET ShoppingCartId=@ShoppingCartId WHERE SessionId=@SessionId
END
GO
EXEC usp_AssignCart 1
GO

下面的存储过程通过向内存优化表中插入大量数据行来测试本地编译的存储过程的性能。该脚本插入了1,000,000行数据。

需要注意的是如果写事物日志文件变成应用的性能瓶颈,SQL Server允许您采用非持久化的表(DURABILITY=SCHEMA_ONLY)来完全除去写事务日志。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
-- natively compiled stored procedure for inserting a large number of rows
-- this demonstrates the performance of native procs
CREATE PROCEDURE dbo.usp_InsertSampleCarts @StartId int, @InsertCount int
WITH NATIVE_COMPILATION, SCHEMABINDING, EXECUTE AS OWNER
AS
BEGIN ATOMIC
WITH (TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'us_english')
DECLARE @ShoppingCartId int = @StartId
WHILE @ShoppingCartId < @StartId + @InsertCount
BEGIN
INSERT INTO dbo.ShoppingCart VALUES
(@ShoppingCartId, 1, '2013-01-01T00:00:00'NULL)
SET @ShoppingCartId += 1
END
END
GO
-- insert 1,000,000 rows
DECLARE @StartId int = (SELECT MAX(ShoppingCartId)+1 FROM dbo.ShoppingCart)
EXEC usp_InsertSampleCarts @StartId, 1000000
GO
-- verify the rows have been inserted
SELECT COUNT(*) FROM dbo.ShoppingCart
GO

使用SSMS创建本地编译的存储过程:

1. 在 Object Explorer中,右键单击您的数据库中的Stored Procedures 节点,点击New,然后点击 Natively Compiled Stored Procedure。创建本地编译的存储过程的模板将会显示在界面上。   

2. 替换模板中的参数,点击Query 菜单下的 Specify Values for Template Parameters。快捷键是Ctrl-Shift-M。   

SQL Server功能支持

很多SQL Server功能所支持的内存驻留OLTP和数据库包含内存优化表。例如,AlwaysOn的组件,日志传送和数据库备份和恢复被完全支持。但是,数据库镜像和复制不被支持。您可以使用SQL Server Management Studio以支持内存优化表和SSIS工作。

对于支持和不支持的功能的完整列表,请参阅到SQL Server 内存驻留OLTP文档。

总结

SQL Server内存驻留OLTP提供了可创造和运行内存优化的极其高效的管理,实现了对OLTP工作负载的性能优化。真正实现了多版本的积极并发控制,且无需在访问过程中锁定。所有内存驻留OLTP内存优化表必须至少拥有一个索引,然后所有对这类表的访问都需要通过这些索引进行。除少量限制情况下外,内存驻留OLTP内存优化表可以作为基于磁盘表中的相同引用的事务。本地编译的存储过程以最快的方式来使用您的内存优化表和性能业务逻辑计算。

本文转自UltraSQL51CTO博客,原文链接: http://blog.51cto.com/ultrasql/1626514,如需转载请自行联系原作者

SQL Server 2014新功能 -- 内存中OLTP(In-Memory OLTP)相关推荐

  1. SQL Server 2016 新功能之综述

    冬去春来,发现之前最后一篇写在2012年,又过去了5年了,时间如飞啊.那时候SQL 2012 发布让人兴奋了一把,哪知道时间如刀,刀刀催人老啊,今天SQL 2016都发布了很久了,很快SQL On l ...

  2. [SQL Server 2014] SQL Server 2014新特性探秘

    SQL Server 2014新特性探秘(1)-内存数据库 简介 SQL Server 2014提供了众多激动人心的新功能,但其中我想最让人期待的特性之一就要算内存数据库了.去年我再西雅图参加SQL ...

  3. SQL Server 2014新特性:其他

    SQL Server 2014新特性:其他 AlwaysOn 增强功能 SQL Server 2014 包含针对 AlwaysOn 故障转移群集实例和 AlwaysOn 可用性组的以下增强功能: &q ...

  4. Sql Server 2016新功能之Row-Level Security(值得关注)

    Sql Server 2016 有一个新功能叫 Row-Level Security ,大概意思是行版本的安全策略(原来我是个英语渣_(:з」∠)_) 直接上例子.这个功能相当通过对表添加一个函数作为 ...

  5. 无废话-SQL Server 2005新功能(1) - TSQL

    无废话-SQL Server 2005新功能(1) - TSQL SQL Server 2005相对于SQL Server 2000改进很大,有些还是非常实用的. 举几个例子来简单说明 这些例子我引用 ...

  6. SQL Server 2014新特性——基数评估(白皮书阅读笔记)

    基数评估 目录 基数评估 说明 基数评估准确的重要性 模型假设 启用新的基数评估 验证基数评估的版本 在迁移到新的基数评估前要测试 校验基数评估 偏差问题 需要手动处理的变化 避免因为新的CE造成性能 ...

  7. SQL Server 2012新功能

    SQL Server 2012 对微软来说是一个重要产品.微软把自己定位为可用性和大数据领域的领头羊. 1. AlwaysOn -这个功能将数据库的镜像提到了一个新的高度.用户可以针对一组数据库做灾难 ...

  8. SQL Server 2017 新功能分享

    本篇文章是我在MVP直通车分享的关于SQL Server 2017的新功能,现在ppt分享如下,可以点击这里下载. 转载于:https://www.cnblogs.com/CareySon/p/SQL ...

  9. 【SQL 编程你也行】SQL Server 2012新功能之函数:choose函数

    choose(id,value1,value2,value3,...) choose函数可以根据传入的id值,返回值所对应的参数值,比如传入2,那么就返回 value1,value2,value3,. ...

最新文章

  1. 【FFmpeg】自定义回调函数处理AVIOContext中的数据
  2. 大前端开发者需要了解的基础编译原理和语言知识
  3. css实现文字在横线上居中
  4. c语言寻找James,[semi-tutorial]某亚里亚写在JamesM边上的OS笔记
  5. python获取机器唯一标识_python中uuid来生成机器唯一标识
  6. Java 多个引用类型变量引用同一个对象
  7. 嵌入式linux面试题解析(二)——C语言部分三
  8. .NET Hacks Tips
  9. 递归法:实现指数型枚举(二叉树递归)
  10. 使用hive计算每一年的最大气温的日期+温度
  11. 信息安全之程序实现简单替换加密,并用字母频率统计进行破解
  12. 软件测试必问必背面试题
  13. KubeCon上海“行业客户云原生最佳实践日“成功举办,云原生在各行业落地生花...
  14. asp.net知识共享平台
  15. CSAPP第七章家庭作业参考答案
  16. 华为鸿蒙智慧屏和手机,【荣耀智慧屏评测】鸿蒙初体验:荣耀智慧屏跨系统交互构建新生态(全文)_荣耀 智慧屏_手机评测-中关村在线...
  17. 微信小程序实现拍照功能
  18. P4在table中使用ternary匹配
  19. 我是如何在一晚上拿到阿里巴巴offer的?
  20. 安全生产六步法是什么_海孜煤矿安全生产管理“六步法”实施办法.doc

热门文章

  1. java token生成和验证_程序员应该如何设计更优雅的Token认证方式?
  2. Java三层结构的概念_Java中的mvc和三层结构究竟是什么关系
  3. key redis 模糊查询个数_Reids Lua 模糊查询所有key 及 相对应的集合总数
  4. github 思维导图开元软件_Windows上有哪些很棒思维导图的软件
  5. 我的世界pc正版好玩的服务器,都来看看好玩的服务器
  6. Android接入unityads广告,Unity Ads胡敏:开发者如何通过广告获取成功
  7. Spring @ComponentScan
  8. python Binary I/O
  9. oracle linux hugepage,LInux下为什么配置HugePages及配置步骤
  10. linux 64位module内联汇编,@yuanbor: Linux内联汇编总结