【0】基本介绍

【0.1】概述介绍

官网:https://docs.microsoft.com/zh-cn/sql/relational-databases/in-memory-oltp/introduction-to-memory-optimized-tables?view=sql-server-ver15

内存优化表是使用 CREATE TABLE (Transact-SQL) 创建而成的表。

默认情况下,内存优化表具有完全持久性。与(传统)基于磁盘的表上的事务一样,内存优化表上的事务具有完全原子性、一致性、隔离性和持久性 (ACID)。 

内存优化表和本机编译的存储过程仅支持一部分 Transact-SQL 功能。

自 SQL Server 2016 起以及在 Azure SQL 数据库中,内存中 OLTP 特定的 排序规则或代码页 没有任何限制。

内存优化表的主存储器是主要内存。 从内存读取表中的行和将这些行写入内存。 表数据的另一个副本维护在磁盘上,但仅用于持续性目的。

有关持久表的详细信息,请参阅 创建和管理用于内存优化的对象的存储 。 在数据库恢复期间(例如, 在服务器重启后),内存优化表中的数据只能从磁盘读取。

为了获得更大的性能提升,内存中 OLTP 支持事务持续性延迟的持久表。 延迟的持久事务在提交事务并将控制权归还客户端后不久即保存到磁盘。 作为提高性能的代价,在服务器崩溃或故障转移过程中将丢失已提交但未保存到磁盘的事务。

除了默认持久的内存优化表之外, SQL Server 还支持非持久的内存优化表,不记录这些表的日志且不在磁盘上保存它们的数据。 这意味着这些表上的事务不需要任何磁盘 IO,但如果服务器崩溃或进行故障转移,则无法恢复数据。

内存中 OLTP 与 SQL Server 集成,以便在所有方面(如开发、部署、可管理性和可支持性)提供无缝体验。 数据库可包含内存中对象以及基于磁盘的对象。

内存优化表中的行是版本化的。 这意味着表中的每行都可能有多个版本。 所有行版本均维护在同一个表数据结构中。 行版本控制用于实现对同一行的并发读取和写入。 有关对同一行的并发读取和写入的更多信息,请参阅 内存优化表中的事物

下图展示多版本控制。 该图显示了一个包含三行的表,其中,每行都有不同的版本。

sql server 优化磁盘性能 sql server 内存优化表_存储过程

该表有三行:r1、r2 和 r3。 r1 有三个版本,r2 有两个版本,r3 有四个版本。 注意,同一行的不同版本不必占用连续的内存位置。 不同的行版本可分散到整个表数据结构中。

可将内存优化的表数据结构视为一个行版本集合。 基于磁盘的表中的行以页和区形式组织,各个行借助页码和页偏移量进行寻址,而内存优化表中的行版本则借助 8 字节的内存指针进行寻址。

可通过以下两种方式访问内存优化表中的数据:

  • 通过本机编译的存储过程。
  • 通过本机编译的存储过程之外的解释型 Transact-SQL。 这些 Transact-SQL 语句可位于解释型存储过程内,也可以是临时 Transact-SQL 语句

【0.2】性质概念总结

(1)内存优化表具有完全持久性(可以设置持久或者完全内存),且具有事务ACID属性。且支持延迟性事务

(2)如果重启了,内存优化表中的数据只能从磁盘读取。

(3)无锁机制,  并发(如闩锁争用或阻塞)影响

(4)内存优化表中的行是版本化的(且默认是快照隔离级别),不占用tempdb空间

(5)内存优化表可以额外支持下列方式

  • 通过本机编译的存储过程。
  • 通过本机编译的存储过程之外的解释型 Transact-SQL。 这些 Transact-SQL 语句可位于解释型存储过程内,也可以是临时 Transact-SQL 语句。

 

【1】基本使用

官网:https://docs.microsoft.com/zh-cn/sql/relational-databases/in-memory-oltp/survey-of-initial-areas-in-in-memory-oltp?view=sql-server-ver15

【1.0】使用大概步骤与限制

步骤:

(1)创建数据库和MEMORY_OPTIMIZED_DATA文件组(alter database add filegroup,每个数据库只能有一个MEMORY_OPTIMIZED_DATA文件组!!)

(2)添加一个存放数据文件的文件夹到文件组(请不要预先创建好这个文件夹,用alter database add file() to filegroup)

(3)创建持久化/非持久化 的内存优化表(sql server2014默认是持久化的),同时你还必须定义一个基于非聚集哈希索引的主键哈希索引是在内存优化表中唯一支持的索引类型。

(4)使用本地编译存储过程:内存优化表支持本地编译存储过程,只要那些存储过程只引用内存优化表。

 

限制:

(1)内存优化表必须放在有 CONTAINS MEMORY_OPTIMIZED_DATA 文件组的数据库下。

(2)内存优化表必须定义一个基于非聚集哈希索引的主键,且该表不支持外键约束检查

(3)内存优化表必须要有足够的内存,否则插入更新等操作会失败

(4)SQL Server 2014对这些表有着很多限制。例如,它们不支持外键或约束检查(感觉类似于MySQL的memory存储引擎),它们也不支持IDENTITY 字段或DML触发器。

 

use master
go
--[1.0] create database
create database test3;

--[1.1] create filegroup contains memory_optimized_data;
alter database test3
add filegroup memory_FG CONTAINS memory_optimized_data;
go


--[2.0]create a store folder for memory_fg
 alter database test3
 add file
 (
    name='memory_on_file',
    filename='c:\mssql\memory_fg_file'

 )
 to filegroup memory_FG
 go

 --[3.0] create a memory table
 use test3;
create table memory_test
(
    id int not null primary key nonclustered hash with(bucket_count=1024)
    ,st1 nvarchar(100)
    ,st2 nvarchar(100) 
)
with (memory_optimized=on,durability=schema_and_data);

insert into memory_test values(1,'a','b');

 

 

【1.1】创建数据库与MEMORY_OPTIMIZED_DATA文件组

use master
go
--[1.0] create database
create database test3;

--[1.1] create filegroup contains memory_optimized_data;
alter database test3
add filegroup memory_FG CONTAINS memory_optimized_data;
go

 

注意ALTER DATABASE语句中的ADD FILEGROUP 语句包含文件组的名称(HekatonFG)和关键字CONTAINS MEMORY_OPTIMIZED_DATA

它会指导SQL Server去创建支持内存OLTP引擎所必需的文件组类型。

注意:每个数据库只能有一个MEMORY_OPTIMIZED_DATA文件组!!

可以通过SSMS属性查看文件组,或者  sys.database_files df join sys.filegroups 来查看文件组是否存在。

   

sql server 优化磁盘性能 sql server 内存优化表_内存优化_02

 

 

 

【1.2】添加一个存放数据文件的文件夹到文件组

添加一个存放数据文件的文件夹到文件组(请不要预先创建好这个文件夹,用alter database add file() to filegroup)

--[2.0]
use master;
create a store folder for memory_fg
 alter database test3
 add file
 (
    name='memory_on_file',
    filename='c:\mssql\memory_fg_file'

 )
 to filegroup memory_FG
 go

注意:在ADD FILE 语句中,我们只为文件路径提供了一个友好的名称。

并且,在TO FILEGROUP 语句中,指定刚才新建的文件组名字

  

sql server 优化磁盘性能 sql server 内存优化表_SQL_03

 

 

   

sql server 优化磁盘性能 sql server 内存优化表_内存优化_04

sql server 优化磁盘性能 sql server 内存优化表_存储过程_05

【1.3】创建内存优化表

 

--[3.0] create a memory table
 use test3;
create table memory_test
(
    id int not null primary key nonclustered hash with(bucket_count=1024)
    ,st1 nvarchar(100)
    ,st2 nvarchar(100) 
)
with (memory_optimized=on,durability=schema_and_data);

insert into memory_test values(1,'a','b');

 

说明:

  ResellerID 字段包含了定义为非聚集哈希的主键。

  注意,必须包含一个WITH 语句来指定BUCKET_COUNT 的设置,它表明了在哈希索引中应该创建的bucket数量。

  (每个bucket是一个槽,可以用来存放一组键值对。)

  微软建议bucket的数量应是一到两倍于你所期望的表所要包含的唯一索引键的数量。

  由于每个数据库只能有一个MEMORY_OPTIMIZED_DATA文件组,所以创建表的时候就不需要指定表创建在哪个MEMORY_OPTIMIZED_DATA文件组了

  此表定义以第二个WITH 语句结束。

这里你指定MEMORY_OPTIMIZED 选项为ON(off为普通磁盘表,off为默认选项) 以及DURABILITY 选项为SCHEMA_AND_DATA(schema_only是单纯的内存表,没有持久化),此选项是针对持久表的。

 

报错:表示只支持nvarchar

  

sql server 优化磁盘性能 sql server 内存优化表_存储过程_06

 

 

 

【2】参考文档

试试sql server2014内存优化表:

 

sql server 优化磁盘性能 sql server 内存优化表_存储过程_07