This article will cover the usage details and performance advantages of the memory-optimized table variables.

本文将介绍内存优化表变量的用法细节和性能优势。

A table variable is a sort of variable that is used to store data temporarily. Disk-based table variables are created in the TempDB database by SQL Server and their life cycle begins and ends on this database. In this context, database performance issues in TempDB directly influence the performance of the disk-based table variables.

表变量是一种用于临时存储数据的变量。 SQL Server在TempDB数据库中创建基于磁盘的表变量,它们的生命周期在该数据库上开始和结束。 在这种情况下,TempDB中的数据库性能问题直接影响基于磁盘的表变量的性能。

With the SQL Server 2014 version, the memory-optimized tables were introduced and they are impacting performance positively due to low-latency and high throughput benefits. There are two durability options available for the memory-optimized tables.

在SQL Server 2014版本中,引入了内存优化表,由于低延迟和高吞吐量的优势,它们对性能产生了积极影响。 对于内存优化的表,有两个可用的耐用性选项。

SCHEMA_AND_DATA option enables us to preserve schema and data at the same time so we don’t carry any losing data risk.

SCHEMA_AND_DATA选项使我们能够同时保留架构和数据,因此我们不会承担任何丢失数据的风险。

SCHEMA_ONLY option preserves only the schema of the table. For this reason, we lose the data when the server is restarted. Particularly, non-durable memory-optimized tables produce zero disks I/O because they solely use the memory resources to store the data. On the other hand, data does not preserve on disk, it means that if the SQL Server engine is restarted, we will lose the data but table schema will be re-created. The memory-optimized table variable offers advanced performance with the minimum latency by using the memory-optimized infrastructure. Also, if we decide to use them we don’t require any application code changes.

SCHEMA_ONLY选项仅保留表的架构。 因此,重新启动服务器时我们会丢失数据。 特别是,非持久的内存优化表产生零磁盘I / O,因为它们仅使用内存资源来存储数据。 另一方面,数据不会保留在磁盘上,这意味着如果重新启动SQL Server引擎,我们将丢失数据,但将重新创建表架构。 通过使用内存优化的基础架构,内存优化的表变量以最小的延迟提供了高级性能。 另外,如果我们决定使用它们,则不需要任何应用程序代码更改。

什么是内存优化表类型? (What is the memory-optimized table type?)

The memory-optimized table type is used to specify a predefined table definition. The following query will create a memory-optimized table type.

内存优化的表类型用于指定预定义的表定义。 以下查询将创建内存优化的表类型。

CREATE TYPE CustomerType AS TABLE
(CustomerID         INT NOT NULL, CustomerName       NVARCHAR(100) NOT NULL, CustomerCreateDate DATETIME NOT NULL, INDEX IDX HASH(CustomerID)WITH(BUCKET_COUNT = 100)
) WITH
(MEMORY_OPTIMIZED = ON
)

In this syntax, some keywords may draw our attention to their differences;

使用这种语法,某些关键字可能会引起我们对它们的区别的注意;

MEMORY_OPTIMIZED = ON syntax identifies that this table type will be on the memory-optimized structure. Memory-optimized tables need at least one index to connect rows. This index can be a hash index or a nonclustered index. Individually for this table type, we chose the hash index type so we must set the bucket number. This number specifies the bucket number of the hash index.

MEMORY_OPTIMIZED = ON语法标识此表类型将在内存优化的结构上。 内存优化表至少需要一个索引才能连接行。 该索引可以是哈希索引或非聚集索引。 单独为此表类型选择哈希索引类型,因此必须设置存储桶编号。 该数字指定哈希索引的存储桶编号。

Tip: For memory-optimized tables we can use two types of indexes. Hash Index offers advanced performance to seek equality values. The nonclustered index will be a good option to seek the range value conditions.

提示:对于内存优化表,我们可以使用两种类型的索引 哈希索引提供了先进的性能以寻求平等价值。 非聚集索引将是寻求范围值条件的一个很好的选择。

When we create any memory-optimized table type, it will be shown under the Types folder in SQL Server Management Studio.

当我们创建任何内存优化表类型时,它将显示在SQL Server Management Studio的Types文件夹下。

When we right-click on the CustomerType and select Properties menu, we can find out the details of the memory-optimized table type. On this screen, the Memory Optimized option shows the type of table type.

当我们右键单击CustomerType并选择Properties菜单时,我们可以找到内存优化表类型的详细信息。 在此屏幕上,“ 内存优化”选项显示表类型的类型。

内存优化表变量 (Memory-optimized table variable)

Memory-optimized table variables do not consume the TempDB resources so they are not affected by any contention and latency issues of the TempDB database. At the same time, they give an outstanding performance relative to disk-based table variables to access the data. We will apply the following steps to create a memory-optimized table variable.

内存优化的表变量不会消耗TempDB资源,因此不会受到TempDB数据库的任何争用和延迟问题的影响。 同时,相对于基于磁盘的表变量访问数据,它们具有出色的性能。 我们将采用以下步骤来创建内存优化的表变量。

  • Type a DECLARE statement to initialize a variable 输入DECLARE语句以初始化变量
  • Assign a name to the variable and this name must start with @ sign 为变量分配一个名称,该名称必须以@符号开头
  • Assign it to a memory-optimized table type after the AS keyword 在AS关键字之后将其分配给内存优化的表类型
  • CRUD operations can be performed 可以执行CRUD操作
DECLARE @TestTableVar AS CustomerType
INSERT INTO @TestTableVar VALUES(1,'Henry Lawrence', '20200305')
SELECT * FROM @TestTableVar

Now we will prove zero I/O concept of this table variable types. After enabling the STATISTICS IO option, the query editor displays the statistical values of the disk activity generated by the query. We will enable this option for the previous query and will execute it.

现在,我们将证明此表变量类型的零I / O概念。 启用S​​TATISTICS IO选项后,查询编辑器将显示查询生成的磁盘活动的统计值。 我们将为上一个查询启用此选项并执行它。

SET STATISTICS IO ON
GO
DECLARE @TestTableVar AS CustomerType
INSERT INTO @TestTableVar VALUES(1,'Henry Lawrence', '20200305')
SELECT * FROM @TestTableVar

The result is not surprising, we have not seen any I/O activity because it uses the memory-optimized algorithm.

结果不足为奇,因为它使用内存优化算法,所以我们没有看到任何I / O活动。

The memory-optimized table variables allow us to create the following constraints and we can define these constraints with the declaration of the table type.

内存优化的表变量使我们可以创建以下约束,并且可以使用表类型的声明来定义这些约束。

  • Unique 独特
  • Null 空值
  • Check 检查一下
CREATE TYPE MemoryTypeCons AS TABLE
(ID INT PRIMARY KEY NONCLUSTERED,
Col1 VARCHAR(40) UNIQUE,
Col2 VARCHAR(40) NOT NULL,
Col3 int CHECK (Col3>=20)
) WITH
(MEMORY_OPTIMIZED = ON
)
GO
DECLARE @ConsTable AS MemoryTypeCons
INSERT INTO @ConsTable
VALUES(1,'Value1',12 , 20)
SELECT * FROM @ConsTable

Memory-optimized table variables do not allow to create a clustered index, for this reason, we have to define primary key constraint as a nonclustered.

内存优化的表变量不允许创建聚簇索引,因此,我们必须将主键约束定义为非聚簇。

  • Tip: Columnstore indexes are used to store large data in the columnar format, unlike the row-based storage technology. Memory-optimized table variables do not allow creating this type of indexes on it. When we try to create a columnstore index, we will get the following error提示:与基于行的存储技术不同,列存储索引用于以列格式存储大数据。 内存优化的表变量不允许在其上创建此类索引。 当我们尝试创建列存储索引时,将出现以下错误
CREATE TYPE MemoryTypeColumnStore AS TABLE
(ID INT PRIMARY KEY NONCLUSTERED,
Col1 VARCHAR(40) UNIQUE,
Col2 VARCHAR(40) NOT NULL,
Col3 int CHECK (Col3>=20),
INDEX IX01_ColumnStore CLUSTERED COLUMNSTORE
) WITH
(MEMORY_OPTIMIZED = ON
)
  • The statement failed because columnstore indexes are not allowed on table types and table variables. Remove the column store index specification from the table type or table variable declaration.
  • 该语句失败,因为不允许在表类型和表变量上使用列存储索引。 从表类型或表变量声明中删除列存储索引规范。

性能基准测试:内存优化的表变量与基于磁盘的表变量 (Performance benchmarking: Memory-optimized table variable vs disk-based table variables)

From the beginning of this article, we have been focusing on the performance advantages of memory-optimized table variables. In this section, we will make a performance test and compare the results of the memory-optimized and disk-based table variables. To perform this test we will use SQLQueryStress because it is very simple and handy to measure the performance result of the queries. At the same time, we will perform the following scenario in the test query.

从本文开始,我们一直专注于内存优化表变量的性能优势。 在本节中,我们将进行性能测试,并比较内存优化和基于磁盘的表变量的结果。 为了执行此测试,我们将使用SQLQueryStress,因为它非常简单且方便地测量查询的性能结果。 同时,我们将在测试查询中执行以下方案。

  • 1001 rows will be inserted to the table variables 将1001行插入到表变量中
  • 100 rows will be deleted from the table variables 将从表变量中删除100行
  • 200 rows of the table variable will be updated 表变量的200行将被更新
  • The remaining rows of the table variables will be fetched by the table variables 表变量的其余行将由表变量获取

At first, we will create the memory-optimized table type.

首先,我们将创建内存优化表类型。

CREATE TYPE TestMemTyp AS TABLE
(Id      INT
PRIMARY KEY NONCLUSTERED,
ODate   DATETIME,
St      TINYINT,
SNumber NVARCHAR(25),
ANumber NVARCHAR(15)
) WITH
(MEMORY_OPTIMIZED = ON
);

Through the following query, we will create the disk-based table type.

通过以下查询,我们将创建基于磁盘的表类型。

CREATE TYPE TestDiskTyp AS TABLE
(Id      INTPRIMARY KEY NONCLUSTERED, ODate   DATETIME, St      TINYINT, SNumber NVARCHAR(25), ANumber NVARCHAR(15)
)

Before we start our performance test, we will use Performance Monitor, also known as Perfmon in order to capture performance statistics of the queries. At first, we will launch the Perfmon and right-click on the performance capturing screen and select the Remove All Counters.

在开始性能测试之前,我们将使用性能监视器(也称为Perfmon )以捕获查询的性能统计信息。 首先,我们将启动Perfmon,然后在性能捕获屏幕上单击鼠标右键,然后选择“删除所有计数器”。

As the second step, we will click the (+) button to add new counters and add the Temp Tables Creation Rate under the SQL Server: General Statistics menu. This counter presents how many temp tables or table variables are created per second.

第二步,我们将单击( + )按钮添加新的计数器,并在“ SQL Server:常规统计信息”菜单下添加“ 临时表创建速率 ”。 该计数器显示每秒创建多少个临时表或表变量。

Our second counter will be Total Latch Wait Time (ms) under the SQL Server: General Statistics and it indicates total latch wait time for the last second.

我们的第二个计数器将是SQL Server:常规统计信息下的总锁存等待时间(ms),它指示最后一秒的总锁存等待时间。

Our last counter will be Batch Requests/Sec under SQL Server: SQL Statistics. This counter represents how many SQL statements received by the SQL engine. This counter solely does not indicate any problem but we will use this counter to track the activity of the server during the execution of the queries.

我们的最后一个计数器将是SQL Server:SQL Statistics下的Batch Requests / Sec 。 此计数器代表SQL引擎接收SQL语句数。 该计数器仅表示没有问题,但是我们将使用该计数器来跟踪查询执行期间服务器的活动。

Now we will start the performance test for the memory-optimized table variable using the SQLQueryStress. In the Number of Iterations box, we can define how many times the query will be executed and we will set this number as 40. The number of Threads determines how many concurrent virtual sessions will execute this query and we will set this number as 20.

现在,我们将使用SQLQueryStress对内存优化的表变量启动性能测试。 在“迭代次数”框中,我们可以定义执行查询的次数,并将此次数设置为40。“线程数”确定执行此查询的并发虚拟会话的次数,并将此次数设置为20。

DECLARE @TestMemOptVar AS TestMemTyp ;
INSERT INTO @TestMemOptVarSELECT SalesOrderId, OrderDate, STATUS, SalesOrderNumber, AccountNumberFROM Sales.SalesOrderHeader SWHERE DueDate <= '2011-10-26 00:00:00.000';
DELETE FROM @TestMemOptVar
WHERE Id <= 43758;
UPDATE @TestMemOptVarSET St = 0
WHERE Id <= 43958;
SELECT *
FROM @TestMemOptVar;

We will click the Database button to determine the database connection and credential settings.

我们将单击数据库按钮来确定数据库连接和凭据设置。

As a final step, we will click the GO button and starts the execution of the query 40 times by the 20 virtual users.

最后一步,我们将单击GO按钮,并开始由20个虚拟用户执行40次查询。

The query took 8.643 seconds to complete. Now we will execute the same query for the disk-based table variable.

该查询花了8.643秒完成。 现在,我们将对基于磁盘的表变量执行相同的查询。

DECLARE @TestDiskOptVar AS TestDiskTyp ;
INSERT INTO @TestDiskOptVarSELECT SalesOrderId, OrderDate, STATUS, SalesOrderNumber, AccountNumberFROM Sales.SalesOrderHeader SWHERE DueDate <= '2011-10-26 00:00:00.000';
DELETE FROM @TestDiskOptVar
WHERE Id <= 43758;
UPDATE @TestDiskOptVarSET St = 0
WHERE Id <= 43958;
SELECT *
FROM @TestDiskOptVar;

The query using the disk-based table variable took 13.053 seconds to complete. Also, you can see the performance monitor result in the below illustration.

使用基于磁盘的表变量的查询完成了13.053秒。 另外,您可以在下图中看到性能监视器的结果。

This line graphic represents, SQL Server can handle more requests for the memory-optimized table variable in a shorter time than disk-based table variables. At the same time, there isn’t any latch issue occurred for it. This performance test has clearly shown us that the memory-optimized table variable performs better performance than the disk-based ones.

此线形图表示,与基于磁盘的表变量相比,SQL Server可以在更短的时间内处理更多的内存优化表变量请求。 同时,没有发生任何闩锁问题。 性能测试清楚地向我们表明,内存优化的表变量比基于磁盘的表变量具有更好的性能。

结论 (Conclusion)

In this article, we discussed the memory-optimized table variables usage details and performance benefits. This type of the variable stores data in the memory so that they don’t produce any disk I/O thus they aren’t affected by any contention or latency which may occur on the TempDB database. This working logic is the biggest advantage against disk-based table variables.

在本文中,我们讨论了内存优化的表变量的用法细节和性能优势。 这种类型的变量将数据存储在内存中,这样它们就不会产生任何磁盘I / O,因此不会受到TempDB数据库上可能发生的任何争用或延迟的影响。 这种工作逻辑是针对基于磁盘的表变量的最大优势。

翻译自: https://www.sqlshack.com/memory-optimized-table-variables-in-sql-server/

SQL Server中的内存优化表变量相关推荐

  1. sql 缓冲池_监视SQL Server中的内存文员和缓冲池分配

    sql 缓冲池 The following article applies to SQL Server versions 2008 + 以下文章适用于SQL Server 2008 +版本 Adequ ...

  2. cte公用表表达式_CTE SQL删除; 在SQL Server中删除具有公用表表达式的数据时的注意事项

    cte公用表表达式 In this article, the latest in our series on Common table expressions, we'll review CTE SQ ...

  3. 在SQL Server中使用JOIN更新表?

    我想更新在其他表上进行联接的表中的列,例如: UPDATE table1 a INNER JOIN table2 b ON a.commonfield = b.[common field] SET a ...

  4. sql server中创建数据库和表的语法

    下面是sql server中创建数据库,创建数据表以及添加约束的sql语句: use master --创建数据库 if exists (select * from sysdatabases wher ...

  5. SQL Server中,备份数据表

    SQL Server中,需要备份数据表及备份表中的数据方法: 执行SQL:select * into 新表名(备份表名) from 原表名 where ···(可以加或不加条件) 上述SQL中,新表名 ...

  6. SQL Server中查询所有的表、视图、列和存储过程

    SELECT * FROM INFORMATION_SCHEMA.TABLES SELECT * FROM INFORMATION_SCHEMA.VIEWS SELECT * FROM INFORMA ...

  7. SQL Server中的表变量

    In this article, we will explore the table variable in SQL Server with various examples and we will ...

  8. SQL Server中的聚集索引与堆

    摘要 (Summary) There are few topics so widely misunderstood and that generates such frequent bad advic ...

  9. SQL Server中的尾日志备份和还原

    A tail-log backup is a special type of transaction log backup. In this type of backup, the log recor ...

最新文章

  1. java输出数组中出现的次数最多的那个及次数
  2. 最新的 PageValidate 类
  3. VS.NET2003调试出现的问题及相关解决方法
  4. sql2008能否打开mysql数据库_SQL Server 2008通过LinkServer访问MySQL数据库
  5. 如何在 Ubuntu 12.04 Server 中安装图形用户界面
  6. 百度云 网盘无法下载,错误提示:MSXML组件版本太低
  7. Dubbo与Zookeeper伪集群部署
  8. 在 Visual Studio Code 中使用 PoweShell - CodeShell
  9. python安卓手机编程入门自学_编程入门学习路线(附教程推荐)
  10. 苹果电脑硬盘数据丢失后如何恢复?
  11. 利用selenium自动登录126邮箱
  12. 我的世界服务器怎么无限刷红石,我的世界:生存最需要的5个红石机器!MC大神才能看懂这操作!...
  13. c语言猴子吃桃问题(简洁做法)
  14. ICC 图文学习——LAB1:Data Setup 数据设置
  15. 关于wmsys.wm_concat() 多条记录合并,及可能出现的异常ORA-31061:XDB错误:special char to escaped char conversion failed
  16. 同步调用和异步调用两者之间的区别
  17. Salesforce Apex 中常用技能总结(持续更新)
  18. OpenCV二值图像连通域分析
  19. 23.Flink-高级特性-新特性-Streaming Flie Sink\介绍\代码演示\Flink-高级特性-新特性-FlinkSQL整合Hive\添加依赖和jar包和配置
  20. Java分页类定义和使用

热门文章

  1. nginx 缓存区太小导致后台Connection reset by peer 报错
  2. ML - 常用数学符号
  3. 取消回车表单自动提交
  4. 【转自Mgen】 .NET(C#):谈谈各种结束进程的方法
  5. 警告 1 warning C4996: ‘scanf‘: This function or variable may be unsafe.
  6. 零基础带你学习MySQL—创建数据库(一)
  7. 有哪些朋友圈励志说说短句?
  8. 如今有线电视还有必要续费吗
  9. 荣耀系列到底算不算华为手机
  10. 客户购买产品的本质是什么,如何快速寻找到客户的需求,提高转化率?