在 Azure SQL 数据库中使用内存中技术优化性能
适用于:Azure SQL 数据库
使用内存中技术可以提高应用程序的性能,并有可能降低数据库的成本。
何时使用内存中技术
使用内存中技术,可以对各种工作负载实现性能改进:
- 事务(联机事务处理 (OLTP)),其中的大多数请求将读取或更新少量的数据(例如,创建/读取/更新/删除 (CRUD) 操作)。
- 分析(联机分析处理 (OLAP)):其中大多数查询具有用于报告目的的复杂计算,还定期计划执行加载(或大容量加载)操作和/或将数据更改写入现有表。 通常,OLAP 工作负荷会定期从 OLTP 工作负荷更新。
- 混合(混合事务/分析处理 (HTAP)),其中针对相同的数据集同时执行 OLTP 和 OLAP 查询。
内存中技术使用查询的本机编译,或者底层硬件上提供的批处理和 SIMD 指令等高级处理来保留应在内存中处理的数据,可以提高这些工作负荷的性能。
概述
Azure SQL 数据库支持以下内存中技术:
- 内存中 OLTP 可以增加每秒处理的事务数,并降低事务处理的延迟。 可受益于内存中 OLTP 的情况包括:高吞吐量事务处理(例如贸易和游戏)、从事件或 IoT 设备引入数据、缓存、数据加载以及临时表和表变量等情况。
- 聚集列存储索引,可减少存储占用(高达 10 倍)并提高报告和分析查询的性能。 将其与数据集市中的事实数据表结合使用,可在数据库中容纳更多数据并提升性能。 此外,将其与操作数据库中的历史数据结合使用,可存档并查询高达 10 倍的额外数据。
- 用于 HTAP 的非聚集列存储索引通过直接查询操作数据库来帮助获取对业务的实时见解,无需运行开销不菲的提取、转换和加载 (ETL) 过程,也无需等待填充数据仓库。 使用非聚集列存储索引可以快速对 OLTP 数据库执行分析查询,同时减少对操作工作负荷的影响。
- 使用适用于 HTAP 的内存优化聚集列存储索引可以针对相同的数据快速执行事务处理和并发运行分析查询。
列存储索引和内存中 OLTP 分别在 2012 年和 2014 年引入 SQL Server。 Azure SQL 数据库、Azure SQL 托管实例和 SQL Server 共享内存中技术的相同实现。
注意
有关使用 AdventureWorksLT
示例数据库和 ostress.exe 演示内存中 OLTP 技术的性能优势的详细分步教程,请参阅 Azure SQL 数据库中的内存中示例。
内存中技术的优势
由于查询和事务处理的效率提升,内存中技术还可降低成本。 用户通常不需要升级数据库的定价层即可实现性能提升。 在某些情况下,即使是降低定价层,使用内存中技术也能提升性能。
使用内存中 OLTP,仲裁商业解决方案能够使其工作负荷增加一倍,同时节省 70% 的 DTU。 有关详细信息,请参 Azure SQL 数据库中的内存中 OLTP。
注意
内存中 OLTP 在 Azure SQL 数据库的高级 (DTU) 和业务关键 (vCore) 服务层级中提供。 “超大规模”服务层级支持一部分内存中 OLTP 对象。 有关详细信息,请参阅超大规模限制。
除基本层和服务目标低于 S3 时的标准层外,所有服务层级均提供列存储索引。 有关详细信息,请参阅更改包含列存储索引的数据库的服务层级。
本文介绍了特定于 Azure SQL 数据库的内存中 OLTP 和列存储索引的各个方面,还包括一些示例,可让你了解:
- 这些技术对存储和数据大小限制的影响。
- 如何控制使用这些技术的数据库在不同定价层之间的移动。
- 内存中 OLTP 以及列存储索引的说明性用法。
有关 SQL Server 的内存中 OLTP 技术的详细信息,请参阅:
- 内存中 OLTP 的概述和使用方案(包括客户案例研究参考和入门信息)
- 内存中 OLTP 的文档
- 列存储索引指南
- 混合事务/分析处理 (HTAP),也称为实时运行分析
内存中 OLTP
内存中 OLTP 技术将所有数据保留在内存中,可以提供极快的数据访问操作。 它还使用专用索引、查询本机编译和无闩锁数据访问来提高 OLTP 工作负荷的性能。 可通过两种方式来组织内存中 OLTP 数据:
内存优化的行存储格式:每个行是一个独立的内存对象。 这是针对高性能 OLTP 工作负荷优化的经典内存中 OLTP 格式。 在内存优化的行存储格式中可以使用两种类型的内存优化表:
- 持久性表 (
SCHEMA_AND_DATA
),其中在服务器重启后仍保留放置在内存中的行。 此类表的行为类似于传统的行存储表,同时具有内存中优化的附加优势。 - 非持久性表 (
SCHEMA_ONLY
),其中重启后不保留行。 此类表适用于临时数据(例如,取代临时表),或者需要快速加载其中的数据,然后将数据移到某个持久性表(称为临时表)的表。
- 持久性表 (
内存优化的列存储格式:其中的数据以纵栏表的格式进行组织。 此结构适用于 HTAP 方案,其中,需要针对运行 OLTP 工作负荷的同一数据结构运行分析查询。
注意
内存中 OLTP 技术适用于完全驻留在内存中的数据结构。 由于无法将内存中数据卸载到磁盘,因此请确保使用具有足够内存的数据库。 有关详细信息,请参阅内存中 OLTP 的数据大小和存储上限。
- 有关内存中 OLTP 的快速入门教程:快速入门 1:通过内存中 OLTP 技术加速 T-SQL 性能。
内存中 OLTP 的数据大小和存储上限
内存中 OLTP 包括用于存储用户数据的内存优化表。 这些表必需在内存可容纳的范围内。 每个服务目标都有内存优化表的内存配额或上限,称为内存中 OLTP 存储。
每个受支持的单一数据库服务目标和每个弹性池服务目标都包括一定数量的内存中 OLTP 存储:
以下各项计入内存中 OLTP 存储上限:
- 内存优化表中的活动用户数据行和表变量。 旧行版本不计入上限。
- 内存优化表中的索引。
- ALTER TABLE 操作的运营开销。
如果达到上限,将会出现超出配额错误,且无法再插入或更新数据。 为了减轻此错误,请删除数据或增加数据库或弹性池的服务目标。
有关监视内存中 OLTP 存储利用率及配置即将达到上限时的警报的详细信息,请参阅监视内存中 OLTP 存储。
关于弹性池
使用弹性池时,池中的所有数据库共享内存中 OLTP 存储。 因此一个数据库中的使用量可能对其他数据库造成影响。 对此,有两个缓解方法:
- 为低于池的 eDTU 或 vCore 计数的数据库整体配置
Max eDTU
或Max vCore
。 此最大值还按比例限制池中任何数据库中的内存中 OLTP 存储利用率。 - 配置大于 0 的
Min eDTU
或Min vCore
。 此最小值可保证池中的每个数据库都有与配置的Min eDTU
或Min vCore
对应的可用内存中 OLTP 存储量。
更改使用内存中 OLTP 技术的数据库的服务层级
Azure SQL 数据库的常规用途、标准和基本服务层级不支持内存中 OLTP。 因此,不能将包含任何内存中 OLTP 对象的数据库缩放到这些层之一。 如果要将数据库扩展到其中一个服务层级,请删除所有内存优化表和表类型以及所有本机编译的 T-SQL 模块,或者将它们转换为基于磁盘的对象和常规 T-SQL 模块。
纵向缩减业务关键或高级数据库时,内存优化表中的数据必须适合数据库或弹性池的目标服务目标中可用的内存中 OLTP 存储。 如果尝试纵向缩减数据库或弹性池,或者将数据库移动到弹性池,而目标服务目标没有足够的可用内存中 OLTP 存储,则操作将失败。
确定内存中 OLTP 对象是否存在
可通过编程方式了解给定的数据库是否支持内存中 OLTP。 可执行以下 Transact-SQL 查询:
SELECT DATABASEPROPERTYEX(DB_NAME(), 'IsXTPSupported');
如果查询返回 1
,则此数据库支持内存中 OLTP。
以下查询确定了将数据库缩放到“超大规模”、“常规用途”、“标准”或“基本”服务层级前需要删除的所有对象:
SELECT * FROM sys.tables WHERE is_memory_optimized = 1;
SELECT * FROM sys.table_types WHERE is_memory_optimized = 1;
SELECT * FROM sys.sql_modules WHERE uses_native_compilation = 1;
内存中列存储
使用内存中列存储技术可在表中存储和查询大量数据。 列存储技术使用基于列的数据存储格式和批查询处理,与传统的行导向型存储相比,可将 OLAP 工作负荷中的查询性能提升 10 倍。 此外,与处理非压缩数据相比,处理压缩数据可将性能提升 10 倍。
可以使用两种类型的列存储索引来组织数据:
- 聚集列存储:表中的所有数据以纵栏表的格式进行组织。 在这种类型的索引中,表中的所有行以纵栏表的格式进行定位,该格式可以高度压缩数据,并可让你快速执行分析查询,以及针对表生成报告。 根据数据的性质,数据大小可以减少 10 到 100 倍。 使用聚集列存储索引还可以快速引入大量数据(批量加载),因为超过 100,000 行的大型数据批在存储到磁盘之前会经过压缩。 这种类型的索引非常适合经典数据仓库应用场景。
- 非聚集列存储:其中的数据存储在传统的行存储表中,有一个采用列存储格式的其他索引用于执行分析查询。 使用这种类型的索引可以实现混合事务分析处理 (HTAP):可以针对事务工作负载运行快速实时分析。 针对优化的行存储表执行 OLTP 查询以访问少量的行,同时,针对更适合用于扫描和分析的列存储索引执行 OLAP 查询。 查询优化器根据查询动态选择行存储或列存储格式。 非聚集列存储索引无法减少数据大小,因为原始数据集按原样保留在原始行存储表中。 但是,其他列存储索引的大小比同等 B 树索引要小几个量级。
注意
内存中列存储技术仅在内存中保留处理时所需的数据,不能装入内存的数据将存储在磁盘上。 因此,列存储结构中的数据量可能会超出可用的内存量。
列存储索引的数据大小和存储
列存储索引不需要完全在内存可容纳的范围内。 因此,索引大小的唯一上限是最大整体数据库大小,此大小在基于 DTU 的购买模型和基于 vCore 的购买模型两篇文章中有述。
使用聚集列存储索引时,对基础表存储使用列式压缩。 这种压缩可显著减少用户数据的存储占用,意味着数据库中可容纳更多数据。 使用列式存档压缩可进一步提高压缩率。 可实现的压缩量取决于数据的性质,但 10 倍压缩并不少见。
例如,如果数据库的最大大小为 1 TB,则使用列存储索引实现 10 倍压缩时,该数据库中可容纳总共 10 TB 的用户数据。
使用非聚集列存储索引时,仍以传统行存储格式存储基表。 因此,节省的存储空间小于使用聚集列存储索引节省的空间。 但是,如果使用单个列存储索引取代众多传统非聚集索引,则仍可整体减少表的存储占用。 还可以对基表使用行存储数据压缩。
更改包含列存储索引的数据库的服务层级
如果使用 DTU 购买模型,并且数据库包含列存储索引,则当将数据库缩放到 S3 服务目标以下时,应用程序可能会停止工作。 列存储索引仅在超大规模、业务关键和高级服务层级以及标准服务层级(如果使用 S3 及更高版本)中受支持。 基本服务层级不支持列存储索引。 当将数据库缩放到不受支持的服务层级或服务目标时,列存储索引将变得不可用。 当执行 DML 语句时,系统会维护索引,但从不使用该索引。 果稍后缩放回受支持的服务层级或服务目标,则列存储索引可以立即再次使用。
如果有一个聚集列存储索引,当数据库缩放到不受支持的服务层级或服务目标时,整个表将变得不可用。 删除所有聚集列存储索引,将其替换为行存储聚集索引或堆,然后再进行缩放操作。