
听地址
2016年下半年,由于该项目需要支持快速数据更新和多个用户的高并发负载,因此我尝试使用SQL Server 2016的内存中OLTP创建内存,以满足的负载要求. 项目. 现在,该项目已接近完成. 最后,系统稳定运行,编写了博客内存 sql,并使用内存记录了您的体验.
用外行的话来说,SQL Server 2016的内存中OLTP是使用内存优化表(MOT)实现的内存. MOT驻留在内存中,并且可以使用Hekaton内存引擎进行访问. 查询MOT时,仅从内存中读取数据行,而不会产生磁盘IO消耗;当更新MOT时,数据更新将直接写入内存. 经过内存优化的表可以在磁盘上维护数据的副本. 该副本仅用于持久数据,而不用于数据读写操作.
在内存中,并非所有数据都需要存储在内存中,并且某些数据仍可以存储在磁盘上. 基于磁盘的表(DBT)是传统的表存储结构. 每页为8KB,用于查询和更新DBT,生成磁盘IO操作,将数据从磁盘读取到内存或异步将数据更新写入磁盘.
内存存储最初存储在磁盘上的数据,并使用内存的高速访问来快速查询和更新数据. 但是,内存不仅仅是存储空间的变化,Hekaton内存访问该引擎实现了本机编译的模块,跨容器事务和查询互操作:
内存数据已集成到SQL Server关系引擎中. 使用内存时,客户端应用程序甚至不会感觉到任何更改,并且不需要修改DAL接口. 由于存在查询Interop,任何解释的TSQL脚本都可以透明地访问MOT,但是性能不如本地编译的TSQL脚本高. 使用分布式事务访问MOT时,必须设置适当的事务隔离级别. 建议使用“读已提交”. 如果发生MSSQLSERVER_41333错误,则表明发生交叉事务隔离错误(CROSS_CONTAINER_ISOLATION_FAILURE),因为当前事务的隔离级别太高.

一个,创建一个内存
内存优化表的数据必须存储在包含Memory_Optimized_Data的文件组中. FileGroup可以有多个文件. 每个文件实际上是一个文件夹. 只能创建一个包含Memory_Optimized_Data的文件组.
第一步,创建一个,创建的数据文件数应与CPU核心数一致,并存储在不同的物理磁盘上;


查看代码
步骤2,创建一个包含的内存优化数据的FileGroup,将“ File”添加到FileGroup,该文件实际上是目录(目录),用于存储内存优化的数据文件,主要是CheckPoint文件,用于恢复持久的Optimized. 内存表.

-- Add File Group from memory-optimized data alter database [Test_MemboryDB] add filegroup fg_MemoryOptimizedData contains MEMORY_OPTIMIZED_DATA; alter database [Test_MemboryDB] add file ( name=Test_MemboryDBDirectory, filename=D:\Program Files\Microsoft SQL Server\Test_MemboryDBDirectory ) to FILEGROUP fg_MemoryOptimizedData;

文件组属性: CONTAINS MEMORY_OPTIMIZED_DATA子句,指定文件组来存储内存优化表数据,每个只能指定一个文件组来存储内存优化数据,可以在该文件组下创建多个目录,分布在不同的物理磁盘上,加快了内存优化表数据恢复的速度.
第二,创建内存优化表
内存优化表用于存储用户数据,并且可以持久存储. 数据存储在内存中. 同时,数据的副本将保留在磁盘上. 选项DURABILITY = SCHEMA_AND_DATA指定持久性存储内存优化表;存储在内存中,由选项DURABILITY = SCHEMA_ONLY指定. 在内存优化表上,您可以创建一个非聚集索引或非聚集哈希索引,并在每个内存优化表中至少创建一个索引.


--create memory optimized table create table [dbo].[products] ( [ProductID] [bigint] not null, [Name] [varchar](64) not null, [Price] decimal(10,2) not null, [Unit] varchar(16) not null, [Description] [varchar](max) null, constraint [PK__Products_ProductID] primary key nonclustered hash ([ProductID])with (bucket_count=2000000) ,index idx_Products_Price nonclustered([Price] desc) ,index idx_Products_Unit nonclustered hash(Unit) with(bucket_count=40000) ) with(memory_optimized=on,durability= schema_and_data) go

1,内存优化: MEMORY_OPTIMIZED
[MEMORY_OPTIMIZED = {ON | OFF}]
默认值是OFF,它指定创建的表是硬盘表. 将选项MEMORY_OPTIMIZED设置为ON,并指定创建的表是内存优化表;
2,耐久性: 耐久性
耐久性= {SCHEMA_ONLY | SCHEMA_AND_DATA}
默认值为SCHEMA_AND_DATA,它指定创建的内存优化表是持久性的,这意味着数据更新将持久性地存储在磁盘上. SQL Server重新启动后,可以根据还原副本将内存优化表的数据存储在“磁盘”中. 选项SCHEMA_ONLY指定所创建的内存优化表是非持久性的,这意味着表架构会永久存储在磁盘上,但是任何数据更新都不会持久化到磁盘上. SQL Server重新启动后,内存优化表Data将丢失.
3,哈希索引和范围索引
内存优化表支持哈希索引. 属性BUCKET_COUNT指定为哈希索引创建的存储桶数. 通常,哈希存储桶的数量是数据行数量的1-2倍. 如果无法估计桶数,则创建一个范围索引(NonClustered Index),索引结构为Bw-Tree.

哈希索引由一个数组和多个数据行链组成. 每个数组元素都称为哈希桶. 通过内置的哈希函数,哈希索引的键被映射到哈希桶. 例如,如果哈希索引的键为(Col1,Col2),则根据HashFunction(Col1,Col2)返回的哈希值,将数据行映射到指定的哈希桶;如果将多个键映射到同一哈希桶,则这些键形成一个链. 例如: 数据表结构为(名称,城市),在名称字段上创建哈希索引,并将具有相同哈希值的数据行链接为单向链.

三,创建本地编译的SP
本地编译的SP在创建时会被编译为机器代码,并且整个SP都是原子执行的,这意味着在SP中,整个SP中的所有操作都是原子操作,无论成功还是失败.

create procedure dbo.usp_GetProduct @ProductID bigint not null with native_compilation, schemabinding, execute as owner as begin atomic with (transaction isolation level = snapshot, language = NUS_English) select [ProductID] ,[Name] ,[Price] ,[Unit] ,[Description] from [dbo].[Products] where ProductID=@ProductID end go

1,在SP的本地编译中,可以为参数和变量指定Nullability属性,默认值为NULL
NOT NULL属性: 不能为参数或变量指定NULL值,
2. 本地编译的SP必须包含两个选项: SCHEMABINDING和ATOMIC Block

必须设置两个选项才能使用“原子块”:
3. 解释后的SP与本地编译的SP之间的区别
解释性SP可以访问基于磁盘的表和内存优化的表. 真正的区别在于,解释后的(解释性)SP首次执行时会进行编译,而本地编译(本机编译)SP会在创建时进行编译,然后直接编译为绑定到内存地址的机器代码.
4. 延迟的持久性
在SP的本地编译中,设置Atoic Block选项: DELAYED_DURABILITY = ON使SP能够更新内存优化表,异步写入事务日志并延迟对磁盘的持久性,这意味着如果内存-optimized table维护基于磁盘的副本. 在内存中修改数据后,不会立即将其更新为基于磁盘的副本. 这可能会导致数据丢失,但可以减少磁盘IO并提高数据更新性能.
四个,使用内存优化的表变量和临时表
传统表变量和临时表使用tempdb存储临时数据,而tempdb不是内存. 使用磁盘存储临时表和表变量数据将产生磁盘IO和竞争. SQL Server提供了内存优化表变量,将临时数据存储在内存中. 有关更多信息,请参阅我的博客: “内存中: 在内存中创建临时表和表变量. ”
五,在内存中使用JSON
由于使用JSON,我的第一印象是: 可以没有JSON,无论是将值传递到前端还是前端将数据传递到,使用JSON相比都更加方便到XML,JSON的使用要简单得多. 有关更多信息,请参阅我的博客: “使用TSQL查询和更新JSON数据”
六,内存的事务处理
交叉事务意味着在一个事务中,一条解释的TSQL语句可以访问内存优化表(MOT)和基于磁盘的表(DBT). 在交叉事务中,访问MOT的操作和访问DBT的操作具有其自己独立的事务序列号,就像在大型交叉事务中一样,有两个单独的子事务用于访问MOT和DBT. 在.dm_db_xtp_transactions(Transact-SQL)中,访问DBT的事务由transaction_id标识,访问MOT的事务号由xtp_transaction_id标识. 有关详细信息内存 sql,请参阅我的博客: “内存中: 内存优化表的事务处理”. >
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-190444-1.html
的国际化
送到家的恶狗不打
这就对了哟