ITPub博客

首页 > 数据库 > 数据库开发技术 > 来聊聊HANA数据库的表

来聊聊HANA数据库的表

原创 数据库开发技术 作者:数据库杂记 时间:2023-06-02 06:15:00 0 删除 编辑


来聊聊HANA数据库的表

1、背景

SAP HANA数据库支持两种类型的表:按列(列表)或按行(行表)存储数据的表。SAP HANA针对列存储进行了优化。

从概念上讲,数据库表是一个二维数据结构,其中单元格按行和列组织。然而,计算机内存是按线性序列组织的。要在线性内存中存储表,可以选择如下所示的两个选项。行存储存储包含表中一行字段的记录序列。在列存储中,列的项存储在连续的内存位置中。

2、行表和列表的组织

在SAP HANA数据库中,按列组织的表针对高性能读操作进行了优化,同时还为写操作提供了良好的性能。有效的数据压缩应用于节省内存和加快搜索和计算。此外,SAP HANA数据库的一些特性(如分区)仅对列表可用。基于列的存储通常适用于具有批量更新的大型表。但是,行表上的更新和插入性能更好。基于行的存储通常适用于单次更新频繁的小表。

适用情形

下表概述了可用于决定将数据表存储为列表还是行表的标准:

存储类型 适用情形
列存储 计算通常在单个列或少量列上执行。
根据几个列的值搜索表。
这个表有大量的列。
表有大量的行,需要进行列操作(聚合、扫描等)。
可以实现高压缩率,因为大多数列只包含几个不同的值(与行数相比)。
行存储 应用程序一次只需要处理一条记录(多次选择和/或更新单个记录)。
应用程序通常需要访问完整的记录。
列主要包含不同的值,因此压缩率很低。
既不需要聚合也不需要快速搜索。
表的行数很少(例如,配置表)。

需要注意:

SAP HANA数据库允许将行表与列表连接起来。但是,连接相同存储类型的表效率更高。可以将现有表从一种存储类型更改为另一种存储类型(ALTER table ALTER type)。

基于列存储的优点

列表有几个优点:

  • 更高的数据压缩率
    柱状数据存储允许高效压缩。特别是如果列是排序的,那么在连续内存中会有相同值的范围,因此可以更有效地使用诸如运行长度编码或簇编码之类的压缩方法。

  • 更高的列操作性能
    使用列式数据组织,对单列的操作(如搜索或聚合)可以通过循环在存储在连续内存位置的数组上实现。这种操作具有较高的空间局部性,并且有效地利用了CPU缓存。

此外,高效的数据压缩不仅可以节省内存,还可以提高速度。

  • 消除附加指标
    在许多情况下,列式数据存储消除了对额外索引结构的需求,因为在列中存储数据就像为每个列建立一个内置索引一样:内存中列存储的列扫描速度和压缩机制(尤其是字典压缩)已经允许具有非常高性能的读取操作。在许多情况下,不需要有额外的索引结构。消除索引可以减少内存大小,提高写性能,并减少开发工作量。但是,这并不意味着在SAP HANA中根本不使用索引。主键字段总是有一个索引,如果需要,还可以创建额外的索引。此外,全文索引用于支持全文搜索。

  • 消除物化聚合
    由于它的列扫描速度快,列存储使得动态计算大量数据的聚合成为可能,而且性能很高。这在许多情况下消除了对物化聚合的需要。消除物化聚集体有几个好处。简化了数据模型和聚合逻辑,提高了开发和维护效率;它允许更高级别的并发性,因为写操作不需要独占锁来更新聚合值;并且它确保聚合值始终是最新的(物化聚合有时仅在预定时间更新)。

  • 并行化
    基于列的存储也简化了使用多个处理器内核的并行执行。在列存储中,数据已经垂直分区。这意味着对不同列的操作可以很容易地并行处理。

3、历史表

SAP HANA支持允许对历史数据进行查询的历史表(也称为基于时间的查询)。

历史表是特殊的数据库表,只允许插入。对历史表的写操作不会物理地覆盖现有记录。相反,写操作总是将数据记录的新版本插入数据库。历史表中的最新版本称为当前数据。同一数据对象的所有其他版本都包含历史数据。历史表中的每一行都有类似于时间戳的系统属性,这些属性表示该行中的记录版本为当前版本的时间段。可以通过请求对数据库的历史视图执行查询来读取历史数据(SELECT…AS OF TIME)。或者,您可以将数据库会话置于历史模式,以便根据历史视图处理所有后续查询。目前,SAP HANA只支持基于列的历史表。

SAP HANA中的历史表对应于SQL中系统版本的临时数据。对于系统版本的临时数据,时间戳是自动设置的,并在数据处于当前状态时指示所谓的事务时间。更新时,系统会自动创建新版本。

基于时间的查询是针对与历史时间点对应的数据库的一致视图的读操作。要启用基于时间的查询,必须将所涉及的表创建为历史表。只有对于历史表,才会创建和填充历史存储。

用户可以通过 SQL 来创建 Temporal Table ,比如通过下面这样的形式。
如果查询过去的历史记录,则可以考虑使用一下的SQL 语法。查询相同的数据在不同时间的变化需要通过两个参数,一个是数据更新时最后事务提交的COMMIT ID,另一个是需要指定时间戳。

CREATE GLOBAL TEMPORARYCOLUMN TABLE 表名(字段名类型);
eg: CREATE GLOBAL TEMPORARY TABLE TEST (A int , B int , C int )
SELECT * FROM <TABLENAME>AS OF CPMMIT ID XXX
或
SELECT * FROM <TABLENAME>AS OF UTCTIMESTAMP '2018-11-23 10:50:00'

4、文档存储

SAP HANA文档存储(通常称为“DocStore”)是JSON构件的存储,允许对JSON进行本地操作,包括过滤、聚合和将JSON文档与HANA列或行存储表连接起来。

JSON文档(JavaScript Object Notation)存储在所谓的集合中。JSON文档的内容可能是深度结构化的,但与XML不同的是,它没有模式。这意味着可以插入任何有效的JSON数据,而无需首先声明其结构。

集合对用户来说就像表一样,用户可以以类似的方式在SQL中使用集合。例如,可以使用常规的INSERT语句插入数据,并通过SELECT读取数据。您可以在单个语句中从表和集合中读取数据,也可以通过与任何其他列或行存储表连接来组合表和集合。

HANA事务在一个数据库中跨越所有三种存储类型(列、行和文档存储),符合数据管理的所有原则:原子性、一致性、隔离性和持久性。

从技术上讲,集合以专用的二进制格式存储;然而,在SQL中,它们被定义为具有自己的子类型的表。你可以根据表类型值“COLLECTION”来选择集合:

SELECT * FROM tables WHERE table_type = 'COLLECTION'

关于DocStore的全部技术细节,请参见SAP HANA开发人员指南。

关于特定于docstore的SQL语句的详细信息请参见《SAP HANA SQL参考》和《系统视图指南》。下面的示例演示了如何创建、更新和读取客户详细信息集合。INSERT语句说明了嵌套JSON数据的语法和结构,相应的SELECT语句显示了使用路径表达式来导航JSON文档的内容:

create collection Customers;
insert into Customers values('{"name": "Paul",
                "address": {
                "street": "Main Street 10",
                "city": "Heidelberg"
                }
                }'
);
select * from Customers where "address"."city" = 'Heidelberg';
select "address"."city", count(*) from Customers group by "address"."city";

因为没有模式来强制数据类型的一致使用,所以您可能需要实现自己的策略来确保数据被一致地插入。

启用文档存储

启用文档存储文档存储是SAP HANA数据库的一个可选特性,您必须为每个租户数据库创建该特性。每个租户只能使用一个DocStore进程。使用ALTER DATABASE语句创建DocStore:

ALTER DATABASE <database name> ADD 'docstore'

注意,一旦创建了DocStore并向其添加了集合,就只能通过首先删除所有集合来从横向视图中删除它。文档存储仅在docstore服务器进程中运行,集合不能移动到任何其他服务器(如indexserver)。

DocStore没有预先确定的SQL端口,所有通信都通过普通索引服务器路由。

诊断

您可以使用数据库诊断(跟踪)来分析DocStore操作的细节。所有DocStore跟踪组件都可以通过“DocStore *”前缀来识别。

显式设计用于跟踪SQL字符串和中间结果的跟踪具有后缀“*_data”。这些跟踪可能包含敏感数据,因此,如果跟踪敏感信息是可接受的,则将这些数据跟踪器的跟踪级别设置为DEBUG、INFO或WARNING。跟踪级别ERROR和FATAL不会打印任何额外的敏感信息,在这方面使用是安全的。有关更多信息,请参见配置跟踪。

5. 表和目录一致性检查

使用SAP HANA数据库中可用的存储过程,您可以对数据库目录和数据库表执行一系列一致性检查。

执行数据库检查会影响系统性能。因此,建议您创建一个系统副本,并在那里运行检查,而不是在您的生产系统上。如果您正在运行一个活动/活动(已启用读)系统,则可以在已启用读的辅助系统上运行检查。

表一致性检查

表一致性检查是SAP HANA数据库中可用的一个过程,它对数据库表执行一系列一致性检查操作。手工执行检查。频率取决于你的场景。

要查看check(过程CHECK_TABLE_CONSISTENCY (SYS))执行的检查操作的列表,请执行以下语句:CALL GET_CHECK_ACTIONS ('CHECK_TABLE_CONSISTENCY')。有关更多信息,请参见SAP Note 1977584。

检查的结果记录在GLOBAL_TABLE_CONSISTENCY (_SYS_STATISTICS)视图中。

授权

要手动执行该过程,您必须具有以下系统权限:

  • DATA ADMIN or CATALOG READ

  • DATA ADMIN

手动执行

执行检查前,需要在SQL控制台中执行以下语句或使用SAP HANA hdsql命令行工具开启相应的采集器:

UPDATE _sys_statistics.statistics_schedule SET status = 'Idle' WHERE id = 5047;

若要在发现不一致时接收警报,请执行以下语句激活相应的警报:

UPDATE _sys_statistics.statistics_schedule SET status = 'Idle' WHERE id = 83;

你可以通过执行下面的语句来调用表一致性检查:

CALL CHECK_TABLE_CONSISTENCY ('<action>', '<schema_name>', '<table_name>')

如果您的表或模式具有非规范名称,即名称包含小写字符、斜杠“/”或其他特殊字符,则必须在SQL语句中对这些名称加双引号。否则,CHECK_TABLE_CONSISTENCY将对名称进行规范化并将其视为字符串。这意味着,例如,在SYSTEM模式中,一个名为“ABC/ ABC”的表,你应该这样调用它:

CALL CHECK_TABLE_CONSISTENCY('CHECK', 'SYSTEM', '"ABC/abc"');

您可以通过执行以下语句禁用收集器和警报:

UPDATE _sys_statistics.statistics_schedule SET status = 'Inactive' WHERE id = 5047;

UPDATE _sys_statistics.statistics_schedule SET status = 'Inactive' WHERE id = 83;

输入参数

action参数指定要执行的检查操作。

要查看哪些检查操作是可用的,包括它们所做的描述,通过执行以下语句调用过程GET_CHECK_ACTIONS:

CALL GET_CHECK_ACTIONS ('CHECK_TABLE_CONSISTENCY')

要在单个过程调用中执行所有可用的检查操作,请指定check作为操作,如下所示:

CALL CHECK_TABLE_CONSISTENCY ('CHECK', '<schema>', '<table>')

一些检查操作包含在其他检查操作中,因此在执行check操作时不会显式执行。修复操作也从CHECK操作中排除,因为它们不是检查,而是对数据进行更改。

参数schema_name和table_name用于指定要检查的模式和表。如果要检查所有模式中的所有表,那么将这些参数的值指定为NULL。

要对所有表执行所有检查操作,请执行该语句

CALL CHECK_TABLE_CONSISTENCY ('CHECK', NULL, NULL).

目录一致性检查

目录一致性检查是SAP HANA数据库中可用的一个过程,您可以使用该过程对数据库目录执行一系列一致性检查操作。执行此操作的频率取决于您的场景。不要同时运行目录检查和执行DDL操作(例如删除用户),因为这可能导致检查返回多个错误。要么在系统副本上运行目录检查,要么等待其他操作完成。只有在继续收到错误时,才应联系SAP支持。

授权

DATA ADMIN or CATALOG READ.

执行

CALL CHECK_CATALOG ('<action>','<schema_name>','<object_name>','<catalog_object_type>')

输入参数

action参数指定要执行的检查操作。

要查看可用的检查操作,通过执行以下语句调用过程GET_CHECK_ACTIONS:

CALL GET_CHECK_ACTIONS('CHECK_CATALOG')

要在单个过程调用中执行所有可用的检查操作,请指定check作为操作,如下所示:

CALL CHECK_CATALOG(CHECK,<schema_name>','<catalog_object_name>',NULL)

参数schema_name和object_name指定要检查的模式和对象。如果要检查所有模式中的所有对象,那么将这些参数的值指定为NULL。

参数catalog_object_type指定要检查的对象类型。然而,它不被支持。您必须指定NULL作为该参数的值。

要对所有类型的所有对象执行所有检查操作,请执行该语句:

CALL CHECK_CATALOG(‘CHECK’,NULL,NULL,NULL)

结果

这个过程返回一个包含以下列的结果表:

  • SCHEMA

  • OBJECT

  • OBJECT_TYPE

  • ERROR_CODE

  • ERROR_MESSAGE

如果没有发现错误,则结果表为空。如果发现错误,建议您联系SAP Support,以解释结果并就所需的操作提出建议。

6、行存储的重新组织(reorg)

为了恢复内存中的数据片段,可能需要不时地进行行存储重组;您可以在线或离线进行重组。

行存储重组恢复内存中的数据片段,这些数据片段是由于内存段和页面的分配方式而产生的。在重组过程中,碎片页面被移动到其他段,并释放由此产生的空段。

您可以在数据库运行时在线运行该进程,或在数据库重启时离线运行该进程:

  • 离线进程是通过在indexserver.ini文件中设置一系列'row_engine'配置文件参数的值,然后重新启动数据库来运行的。通常,由于没有事务更新活动,通过脱机运行重组可以获得更好的压缩比。

  • 在线进程可以通过使用SQL系统管理语句RECLAIM DATA SPACE执行,也可以通过执行存储过程REORGANIZE_ROWSTORE()执行。这些进程不需要独占访问表,这意味着可以在重组过程运行时更新表。

存储过程REORGANIZE_ROWSTORE()也可以用来估计离线行存储重组的好处,如下所述。

SAP Note 1813245 - SAP HANA DB: Row Store重组提供了运行在线或离线重组之前所需的所有先决条件和准备步骤的详细信息,并提供了离线过程所需的配置更改的详细信息。

SQL RECLAIM DATA SPACE

ALTER SYSTEM RECLAIM [ROW] DATA SPACE [IMMEDIATE] [<host_port>]

对于远程节点上的重组,可以提供可选参数值来指定将在其中进行重组的服务器的主机和端口。如果省略了这些,则在建立当前连接的服务器上进行重组。

使用存储过程:REORGANIZE_ROWSTORE()

使用存储过程而不是SQL语句的一个优点是,存储过程会自动将命令分发给所有正在运行的节点。存储过程的基本语法是:

CALL REORGANIZE_ROWSTORE (‘REORGANIZE’)

使用离线模式,您可以首先估计行存储重组的好处,并评估可能恢复多少内存;使用以下示例中说明的语法。

离线模式估计

估计选项的语法如下:

call reorganize_rowstore (' estimate_memory_saving ', ' offline ');

该过程返回估计的已保存内存大小(以MB为单位)、估计的移动页面大小(以MB为单位)和估计的移动页面计数。

重新组织架构/表/段

reorganize函数的语法在这里给出,该过程也可以针对特定的命名模式和表或特定的段运行:

CALL REORGANIZE_ROWSTORE (' REORGANIZE ', ' TABLE ', ' MySchema ', [' <TABLE_NAME> '])

如果未指定可选参数TABLE_NAME,则将重新组织指定模式中的所有行存储表。

使用SEGMENTS关键字来识别一个或多个要重组的段。在这种情况下,需要一个json字符串来指定片段,如下面的例子所示:

CALL REORGANIZE_ROWSTORE(‘REORGANIZE’, ‘SEGMENT’, ‘[{"location”: ”host1:port1”, "segments”: [3, 4]}, {"location”: "host2:port2”, "semgents”: [5, 6, 7]}]”)

这将重新组织' host1:port1 '上的段3,4和' host2:port2 '上的段5,6,7。

这个过程还包括一个文档参数:REORGANIZE_ROWSTORE ('HELP')

7、列存储的内存管理

列存储是SAP HANA数据库的一部分,用于管理内存中列中组织的数据。作为列表创建的表存储在这里。

列存储针对读操作进行了优化,但也为写操作提供了良好的性能。这是通过两种数据结构实现的:主存储和增量存储。

主存储器包含数据的主要部分。在这里,有效的数据压缩应用于节省内存和加快搜索和计算。然而,对主存储器中的压缩数据进行写操作的成本很高。因此,写操作不会直接修改主存中的压缩数据。相反,所有更改都被写入称为增量存储的单独数据结构中。增量存储只使用基本压缩,并针对写访问进行了优化。读操作在两个结构上执行,而写操作只影响增量。

增量合并操作的目的是将增量存储中收集的更改移动到读优化的主存储中。在增量合并操作之后,主存储器的内容被持久化到磁盘上,如果需要的话,它的压缩会被重新计算和优化。

增量合并操作的另一个结果是增量日志的截断。增量存储结构本身只存在于内存中,不持久化到磁盘。列存储为增量存储上执行的所有操作创建逻辑重做日志项。这个日志叫做delta日志。在系统重新启动的情况下,将重播增量日志项以重新构建内存中的增量存储。在将增量存储中的更改合并到主存储中之后,通过删除在合并操作之前写入的条目来截断增量日志文件。

注意:

因为只有内存中的数据是相关的,所以表的负载状态很重要。表可以有以下几种加载状态之一:

  • 卸载,即表中的任何数据都不加载到主存中

  • 部分加载,即表中的一些数据被加载到主存中,例如,最近在查询中使用的一些列

  • 完全加载,即表中的所有数据都加载到主存中

但是,增量存储中的数据只能完全加载或卸载。不可能部分装载。因此,如果没有执行增量合并,并且表的全部数据都在增量存储中,则表要么是完全加载的,要么是卸载的。

在列存储中加载和卸载数据

SAP HANA数据库旨在将所有相关数据保存在内存中。标准行表在数据库启动时加载到内存中,并且在数据库运行期间一直保留在内存中。他们没有卸载。另一方面,列表是在第一次访问时按需逐列加载的。这有时被称为惰性加载。这意味着不会加载从不使用的列,从而避免了内存浪费。

请注意
这是列表的默认行为。在表的元数据中,可以指定在数据库启动时将单个列或整个表加载到内存中。

例如,如果数据库中的查询或其他进程需要比当前可用内存更多的内存,则数据库可能会主动从内存中卸载表或单个列。它基于最近最少使用的算法。这种卸载机制可以与手动应用的卸载优先级值相结合。优先级值作为0到9之间的数字应用于表;具有较高优先级的表比其他表更早卸载。

要了解更多信息,还可以参考SAP Note 2127458 FAQ: SAP HANA加载和卸载

还可以将列配置为允许一次访问一页主存储,而不是要求整个列都在内存中。这使您能够在某些单独列或整个表驻留在磁盘上时节省内存并在主存储器中查询单个值。要启用该特性,请在CREATE TABLE或ALTER TABLE语句的中指定列描述子句PAGE LOADABLE或column LOADABLE。

从内存中加载/卸载列表

在正常情况下,SAP HANA数据库自动管理表在内存中的加载和卸载,其目的是将所有相关数据保存在内存中。但是,您可以手动加载和卸载单个表,也可以在必要时加载表列。

先决条件

您拥有以下特权之一:

  • 系统权限  TABLE ADMIN

  • 对表或表所在的模式有执行SQL对象特权: UPDATE

上下文

由于SAP HANA数据库自动管理表的加载和卸载,因此通常不需要手动加载和卸载单个表和表列。然而,这可能是必要的,例如:

  • 精确测量特定表(load)使用的总内存量或“最坏情况”内存量

  • 主动释放内存(卸载)

使用管理工具加载和卸载表

上下文

在SAP HANA studio和数据库资源管理器中,使用目录中所选表可用的上下文菜单选项,过程是相同的。在SAP HANA studio中,可以在表定义的Runtime information选项卡上查看有关表当前内存使用情况和加载状态的详细信息。另请参见下面的监视视图M_CS_TABLES。

过程

  1. 在Systems视图中,导航到目录中的表。

  2. 在表的上下文菜单中,根据需要选择“加载到内存”或“从内存卸载”。

  3. 要开始操作,请接受显示的确认提示。

结果

如果加载了一个表,则该表的完整数据(包括其增量存储中的数据)将被加载到主内存中。根据表的大小,这可能需要一些时间。表的加载状态是FULL。

如果您卸载了一个表,则该表的完整数据(包括其增量存储中的数据)将从主内存中卸载。由于数据必须重新加载到内存中,因此对该表的后续访问将会变慢。表的负载状态为NO。

使用SQL加载和卸载表

过程

1、打开SQL控制台并执行所需的语句。LOAD语句支持指定一个或多个表列、增量数据或所有数据的选项。您可以查询监视视图M_CS_TABLES以获得该表的完整详细信息(示例如下)。

  • 加载MyTable到内存中: LOAD MyTable ALL;

  • 加载MyTable的列A和列B到内存:Load MyTable (A, B);

  • 从内存中卸载MyTable: UNLOAD MyTable;

2、查询MyTable表的加载状态:    SELECT loaded FROM m_cs_tables WHERE table_name = 'MyT able';

结果

如果只加载选定的列,则表的加载状态为partial。如果您卸载一个表,则该表的完整数据(包括其增量存储中的数据)将从主内存中卸载。

按对象使用管理内存

您可以使用未使用保留期功能从内存中自动卸载未使用的对象。

SAP HANA有一个内置的内存管理系统,如果可用内存水平过低,该系统会自动从内存中卸载可交换的资源。管理内存的另一种方法是未使用保留期,它会自动从内存中卸载未使用的对象。

请注意
您可以使用M_MEMORY_OBJECTS视图检查对象的总数以及可交换和不可交换大小的使用情况。

未使用保留期

要主动管理内存,即使不存在低内存情况,也可以根据对象的使用频率自动从内存中卸载可交换的对象。基于时间的参数unused_retention_period。在global.ini文件中可用。

要使用此特性,请将默认值(最初设置为0)更改为秒数,例如7200(2小时)。在此时间段内未使用的对象被标记为有资格卸载。

超过保留期的对象不会立即从内存中卸载,一个额外的检查进程以预定义的间隔运行,启动卸载。检查的频率由unused_retention_period_check_interval配置参数控制。默认设置为7200秒(2小时)。

对象的保留时间和优先级

除了常规配置参数之外,还可以对表或分区定义本身应用保留期和卸载优先级值(有关详细信息,请参阅SAP HANA SQL和System Views Reference)。下面的示例对表myTable应用60秒的卸载保留期。

<s:1> ALTER TABLE "myTable" WITH PARAMETERS('UNUSED_RETENTION_PERIOD'='60')

注意,只有在global.ini文件中为unused_retention_period设置了配置值后,保留期值才能应用于表。

卸载优先级值是一个从0到9的数字,其中0表示对象永远不会自动卸载,9表示最早卸载。以下示例将默认值5缩减为2:

ALTER TABLE "myTable" UNLOAD PRIORITY 2

表的卸载优先级保存在TABLES表中:

SELECT UNLOAD_PRIORITY FROM TABLES WHERE TABLE_NAME = "myTable"
请注意
请注意,卸载优先级的更改不会立即生效;更改仅在下一次将表加载到内存中时生效。因此,如果你想立即应用更改,你应该用以下两个语句卸载和重新加载表:

UNLOAD "myTable";
LOAD "myTable" ALL;

由于这些操作对于大型表可能需要很长时间,因此请考虑在营业时间以外的合适时间运行这些作业。

资源具有保留配置权重值,该权重值也影响对象从内存中卸载的顺序。权重与资源最后一次访问以来的时间值一起使用,以计算配置值。优先级6-9对应于“早期卸载”处置,优先级1-5对应于“长期”处置,优先级为零的表是“不可交换”的。配置值可以通过global.ini文件的memoryobjects部分中的一组参数进行配置,尽管这通常不是必需的。参见SAP Note 1999997 - FAQ: SAP HANA Memory。

混合lob(大型对象)

为了节省内存,您可以将LOB数据存储在磁盘上,在这种情况下,数据只在需要时加载到内存中。或者,您可以使用可配置的Hybrid LOB特性,该特性非常灵活,可以根据LOB的大小将LOB存储在磁盘或内存中。

SAP HANA可以将大型二进制对象(lob)(如图像或视频)存储在磁盘上,而不是存储在主存的列或行结构中。这会影响加载到内存中的行存储的大小,从而影响启动和接管时间。保存在磁盘上的LOB仅由相应表列中的ID引用,并根据需要加载到内存中。

这大大减少了主内存的消耗,特别是在实际不请求LOB数据的情况下。LOB数据具有短期处置设置,如果存在内存短缺,则在需要卸载列或表数据之前将其从内存中删除(请参阅下面的缓存消耗)。

管理lob存储的基本选项有:

  • 将所有LOB保存在内存中(LOB大小最多支持1GB)

  • 将所有LOB保存在磁盘上(每个LOB创建一个虚拟文件)

  • 使用可配置的Hybrid特性,该特性根据LOB的大小为LOB使用三种存储类型:最小的LOB存储在内存中,最大的LOB存储在磁盘上,中等大小的LOB一起存储在LOB容器中。

通过在CREATE TABLE和ALTER TABLE命令中设置LOAD UNIT值,可以将大型对象数据列配置为页可加载或列可加载。但是,大型对象数据类型的内存使用由Hybrid LOB配置参数控制,与LOAD UNIT配置无关。虽然对于大型对象数据列,LOAD UNIT可以配置为COLUMN LOADABLE或PAGE LOADABLE,但LOAD UNIT不能决定大型对象数据类型的内存使用情况。另请参阅本机存储扩展主题SAP HANA NSE和分页大对象数据类型。

混合lob的配置

ini中的三个配置文件设置用于实现和管理混合LOB特性。

default_lob_storage_type设置(SQL节)可以设置为内存或混合(默认)。如果激活了Hybrid,则还使用以下两个参数。

对于混合lob,必须将lob_memory_threshold设置(SQL节)设置为字节的数值(默认为1000)。这为最小的lob定义了初始大小阈值。

midsizelob_threshold设置(持久性部分)定义中等大小lob的上限阈值。默认设置为4000(字节),不应低于此值。

然后将lob按以下类型进行分类:

  • 当属性加载时,小lob(类型Inplace)总是完全加载到主存中。

  • 大小介于两个阈值之间的中型lob的存储类型为Packed。这些lob每个属性共享一个LobContainer,并且只在需要时加载到主内存中。

  • 大型lob(类型为File)存储在磁盘上自己的虚拟文件中,并根据需要单独加载到主内存中。

请注意
在系统重新启动期间加载和初始化许多lob的需要可能会对重新启动时间产生相当大的负面影响。Type Packed减少了表示为单个文件的小lob的数量,因此在优化重启时间方面可能是最有效的。对于使用持久内存和快速重启选项的场景,这可能特别有利。

混合LOB特性可以在行存储和列存储中使用,但是类型Packed仅对列存储表实现。

激活混合LOB特性后,将根据新规则存储所有新创建的LOB值。现有LOB值保持不变。如果有必要,可以使用ALTER或CREATE TABLE命令(带有子句(blob、clob等)和可选的memory_threshold_value)回顾性地将该特性应用于表。这将应用lob_memory_threshold设置的值。从SQL命令行应用的值优先于系统设置。

以下示例将值应用于新创建的表。

<e:1>——内存阈值没有值,应用系统设置
create column table <table> (id int, data blob);

这里还显示了应用0(所有lob都保存在磁盘上)和null(所有lob都保存在内存中)值的效果。

-- all lobs are on disk:
create column table <table> (id int, data blob memory threshold 0);
-- all lobs <= 1000 bytes are in memory, larger lobs are on disk:                    
create column table <table> (id int, data clob memory threshold 1000); 
-- all lobs are in memory:
create column table <table> (id int, data nclob memory threshold null); 

注意,内存阈值总是被引用为较小或相等(<=)。

或者,您可以应用midsizelob_threshold系统属性的值,使用带有ALTER table的LOB REORGANIZE子句将列或表转换为使用混合LOB。下面的示例为表的两个指定列执行此操作:

ALTER TABLE 'MyTable' LOB REORGANIZE 'Attachments', 'Pictures'

如果没有指定列,则将阈值应用于表中的所有LOB列。LOB REORGANIZE子句还支持ONLINE模式(或ONLINE PREFERRED),该模式不需要表上的排他锁,因此仍然可以应用数据更新。请参阅SAP HANA SQL参考指南中的ALTER TABLE了解更多信息。

每个表的内存消耗

即使LOB数据存储在磁盘上,您仍然需要在内存中存储一些信息。这些信息可以通过查询M_TABLES, M_CS_TABLES或M_CS_COLUMNS来检索:

SELECT * FROM M_CS_TABLES WHERE SCHEMA_NAME = '<schema>' ORDER BY MEMORY_SIZE_IN_TOTAL DESC;

SELECT * FROM M_CS_COLUMNS WHERE SCHEMA_NAME = '<schema>' AND TABLE_NAME = '<table>' ORDER BY MEMORY_SIZE_IN_TOTAL DESC;

系统的堆内存:HEAP_MEMORY

要查看存储在磁盘上的混合LOB数据实际加载到主存中的主存消耗了多少主存,请使用M_HEAP_MEMORY:

SELECT * FROM M_HEAP_MEMORY WHERE CATEGORY = 'Pool/PersistenceManager/LOBContainerDirectory';

缓存消耗

当LOB存储在磁盘上时,为了加快访问速度,LOB数据缓存在SAP HANA页面缓存中,并进行短期处理。

请注意
不要更改它,因为它会导致性能问题。

在高负载期间,HEAP_MEMORY可能会显著增加(直到达到SAP HANA的一般内存限制)。这没有问题,因为LOB数据首先从页面缓存中卸载,因为它使用短期处置。

对于内存分析,可以清理缓存或重新启动SAP HANA以释放缓存。这两个选项都应该谨慎使用,因为这样卸载所有表并重新加载可能会很昂贵(意味着它可能需要停机时间)。

对于缓存的概述,使用:SELECT * FROM M_MEMORY_OBJECT_DISPOSITIONS

M_MEMORY_OBJECT_DISPOSITIONS显示哪个组件持有哪种类型的处置资源(内存对象是短期、中期、长期还是不可交换)。它不会告诉您缓存页面中存储了哪些数据。

8、Delta合并操作

写操作只在增量存储上执行。为了将数据转换为在内存消耗和读取性能方面得到优化的格式,必须将其传输到主存储器。这是由增量合并操作完成的。

下图显示了合并过程中的不同步骤,涉及哪些对象,以及如何访问它们:
增量合并过程

写操作只在增量存储上执行。为了将数据转换为在内存消耗和读取性能方面得到优化的格式,必须将其传输到主存储器。这是由增量合并操作完成的。

下图显示了合并过程中的不同步骤,涉及哪些对象,以及如何访问它们:
增量合并过程

  1. 在合并操作之前,所有写操作都到增量1存储,所有读操作都从主1和增量1存储读取。

  2. 当合并操作正在运行时,会发生以下情况:
    a. 所有的写操作都到第二个增量存储器,增量存储器2。
    b. 读操作从原始主存储器,主存储器1,以及从增量存储器,增量存储器1和增量存储器2中读取。
    c. Main 1和Delta 1的内容被合并到新的主存储Main 2中。

  3. 合并操作完成后,会发生以下情况:
    a. Main1和Delta1存储被删除
    b. 整个主存储器的内容被持久化到磁盘。

请注意
使用这种双缓冲区概念,表只需要锁定很短的时间:在进程开始时,打开的事务被移动到Delta2,在进程结束时,存储被“切换”。
小心注意
增量合并操作的最小内存,会包括当前主存储的大小加上将来主存储的大小加上当前增量存储的大小加上一些额外的内存。重要的是要理解,即使列存储表被卸载或部分加载,整个表也会被加载到内存中以执行增量合并。

因此,增量合并操作可能会非常昂贵,主要原因如下:

  • 将表中所有列的完整主存储器重写到内存中。这消耗了一些CPU资源,并且至少暂时复制了主存储器所需的内存(当main 1和main 2并行存在时)。

  • 即使只更改了相对较少的记录,完整的主存储也会持久化到磁盘上。这将创建磁盘I/O负载。

这种对性能的潜在负面影响可以通过拆分表来减轻。主存储的大小可以通过将表分成多个分区来减小,每个分区都有自己的主存储和增量存储。增量合并操作在分区级执行,并且只针对实际需要它的分区。这意味着需要合并和持久化的数据更少。注意,也应该考虑分区表的缺点。

分区表上的增量合并

在增量合并操作期间,分区表的每个分区在内部被视为具有自己的数据和增量存储的独立表。只有受影响的分区才会进行合并操作。如上所述,在合并操作期间必须复制整个表,因此对于分区表,合并操作期间所需的主内存量会减少,具体取决于分区的大小。

无论表的数据是在主存储还是增量存储中,都可以对其进行重新分区。但是,如果增量较小,重分区可以更快。

合并的动机

可以通过几种方式触发将表的增量存储合并到其主存储中的请求。这些被称为合并动机。

下图说明了不同的合并动机以及它们是如何被触发的。

自动合并

在SAP HANA中启动合并的标准方法是自动合并。一个名为mergedog的系统进程定期检查本地加载的列存储表,并根据可配置的标准(例如增量存储的大小、可用内存、自上次合并以来的时间等)确定每个单独的表(或分割表的单个分区)是否需要合并。

如果indexserver.ini文件的merge部分中的active参数设置为yes,则自动合并是激活的。

请注意
对于系统视图TABLES (SYS)中的单个表,可以激活和取消自动合并。AUTO_MERGE_ON列的值可以修改为TRUE或FALSE。
请注意
停用表的自动合并也会隐式禁用自动压缩优化(列AUTO_OPTIMIZE_COMPRESSION_ON设置为FALSE)。即使在系统视图TABLES中将AUTO_OPTIMIZE_COMPRESSION_ON列设置为TRUE,情况也是如此。对于禁用自动合并的表,必须手动触发压缩优化。
智能的合并

如果由SAP HANA提供支持的应用程序需要对合并过程进行更直接的控制,SAP HANA支持一个功能,使应用程序能够请求系统检查增量合并现在是否有意义。这个功能被称为智能合并。例如,如果应用程序开始加载相对较大的数据量,则加载期间的增量合并可能会对加载性能和其他系统用户产生负面影响。因此,应用程序可以禁用正在加载的那些表的自动合并,并在加载完成后向数据库发送一个“提示”来执行合并。

当应用程序向数据库发出智能合并提示以触发合并时,数据库将评估确定合并是否必要的标准。如果满足条件,则执行合并。如果不满足标准,则数据库不采取进一步的操作,只有应用程序的后续提示才会触发对标准的另一次评估。

如果indexserver.ini文件的mergedog部分中的smart_merge_enabled参数设置为yes,则智能合并将被激活。

留意
对于要使用智能合并进行合并的表,应该禁用自动合并。否则,自动合并和智能合并可能会相互干扰。 
硬合并

您可以通过执行SQL语句merge delta OF ""手动触发表的增量合并操作。这被称为硬合并,导致数据库在有足够的系统资源可用时立即对表执行增量合并,或者在有足够的系统资源可用时立即执行增量合并。因此,硬合并受制于合并令牌控制机制。

请注意
与系统触发的增量合并操作不同,这里列出的所有手动执行的增量合并操作随后都不会触发表的新主存储的压缩优化。如果表在增量合并操作之前进行了压缩,那么之后它将使用相同的压缩策略进行压缩。如果在增量合并操作之前没有压缩它,那么之后它将保持未压缩状态。因此,在手动增量合并之后,必须手动触发压缩优化。
重要的合并

为了保持系统稳定,数据库可以触发一个关键的合并。例如,在禁用自动合并且没有向系统发送智能合并提示的情况下,增量存储的大小可能会变得太大,无法成功进行增量合并。当超过一定阈值时,系统会自动发起紧急合并。

merge监控器

列表的增量合并操作是一个潜在的昂贵操作,必须根据可用资源和优先级进行管理。这是合并监视器的职责。

系统使用成本函数来决定合并哪个表、何时合并以及以何种顺序合并。还有成本函数控制同时合并多少表以及合并单个表使用多少线程。

合并监视器负责控制单个主机上所有列表的所有合并请求。在分布式系统中,每个索引服务器都有自己的合并监视器。

所有合并请求必须从合并监视器获取合并令牌。合并令牌表示系统资源的分配,并“授权”合并实际开始。如果没有足够的系统资源可用,或者同一个表已经被另一个线程合并,合并监视器将阻止合并请求。这避免了其他线程插入或读取数据时的长时间等待和延迟。

根据当前系统资源消耗、合并动机和各种成本函数的评估,合并监视器允许单个请求合并的线程通过,并释放等待的线程。

成本函数

SAP HANA数据库根据可配置的合并标准或成本函数决定是否执行请求的增量合并以及执行多个请求的顺序。

成本函数可以根据合并动机来配置,即合并是由自动系统进程merge请求(自动合并)、由应用程序提示请求(智能合并)、由SQL语句请求(硬合并)等等。

成本函数在运行时求值,并在indexserver.ini文件的merge部分中进行配置。以下是可用的成本函数:

  • Auto_merge_decision_func和smart_merge_decision_func
    这些代价函数决定是否执行请求的增量合并。

  • Auto_merge_priority_func和smart_merge_priority_func
    这些成本函数决定了分配给增量合并请求的优先级。

  • critical_merge_decision_func
    这个代价函数决定是否执行增量合并。它将运行增量合并,以避免可能导致内存不足或系统崩溃的情况,即使其他成本函数已关闭或无法运行。

  • hard_merge_priority_func
    这个代价函数决定了硬合并的优先级。

  • load_balancing_func
    这个成本函数决定了用于合并处理的系统资源的分配。

请注意
决策代价函数只对每个合并请求求值一次。在智能合并提示触发合并请求的情况下,如果成本函数返回false结果(即,系统决定不需要增量合并),则记录请求,但不进行进一步评估。只有新的提示才有可能启动新的增量合并。

配置开销函数有以下参数:您可以使用它们为所有增量合并配置构建成本函数。

也注意
不建议您更改增量合并的默认设置,除非SAP支持部门指示这样做。

参数含义对照:

Parameter Meaning
DMS Delta memory size [MB]This refers to the size of the table's delta storage.
TMD Table merge delay [sec]This refers to the time since the last merge of table
MRC Main row count [million]This refers to the current number of rows in the main storage of the table.
DMR Deleted main rows [million]This refers to the number of deleted records not in delta storage, but marked as deleted in main storage. Merging makes sense if there are many deleted rows.
DLS Delta log size [MB]
DCC Delta cell count [million]This refers to the current number of cells in the delta storage of the table. For example, if the delta storage contains 3 records, each with 4 columns, then the delta cell count is 12.
DRC Delta row count [million]This refers to the current number of rows in the delta storage of the table.
QDW Queuing delay wait [sec]This refers to the time that a merge thread has been waiting for the merge monitor to allocate it merge tokens. This parameter can be useful if you want to implement a first come first served scheduling strategy.
NAME Table name [string]
SCHEMA Schema name [string]
CLA CPU load average [percentage]
LCC Logical CPU count
THM Total heap memory [MB]
AHM Available heap memory, including memory that could be freed [MB]
DUC Delta uncommitted row count [million]This refers to the number of uncommitted rows in the delta storage of the table.
MMS Main memory size [MB]
UPT Index server uptime [sec]
MMU Main max udiv [million]
OCRC (Last) optimize compression row count [million]
CRCSOC Change row count since (last) optimize compression [million]
RP Table is range partitioned [boolean]
PAL Process allocation limit [MB]

成本函数实例

Cost Function Configuration Meaning
auto_merge_decision_func = DMS>1000 or TMD>3601 or DCC>800 or DMR>0.2*MRC or DLS>5000 如果表的增量存储超过1000mb,或者超过60分钟没有进行合并,或者表的增量单元数超过8亿,或者表的主存中删除的记录超过20%,或者表的增量日志大于5000mb,则执行表的自动增量合并
auto_merge_decision_func = DMS > 1000 or DMS > 42 and weekday(now())=6 and secondtime(now())>secondtime('01:00') and secondtime(now())<secondtime('02:00') 如果表的增量存储的大小超过1000mb,则执行表的自动增量合并,除非是在1.00到2.00之间的星期六,在这种情况下,如果增量存储超过42mb,则会合并。注意一周从星期一开始,第0天。
smart_merge_decision_func = DMS>1000 or DCC>800 or DLS>5000smart_merge_priority_func = DMS/1000 由智能合并提示触发的表的增量合并请求在以下情况下执行:增量存储大于1000mb,或者增量存储中的增量单元数大于8亿,或者增量日志的大小大于5000mb。系统根据增量存储的大小对智能合并请求进行优先级排序,即增量较大的表优先合并。
hard_merge_priority_func = QDW 硬合并触发的增量合并仅通过排队延迟等待来确定优先级,换句话说,基于先进先出的原则。
hard_merge_priority_function = 1/(7+MMS) 硬合并触发的增量合并按表大小排序。较小的表首先合并,其想法是在较大的表开始合并之前先释放一些内存。

合并令牌

增量合并操作可能会给系统带来沉重的负载。因此,需要应用控制以确保合并操作不会消耗所有系统资源。控制机制基于对每个合并操作的合并令牌分配。

除了强制合并之外,除非已分配令牌,否则合并操作无法启动。如果所有的合并令牌都被占用了,合并请求必须等待,或者直到系统释放新的合并令牌,因为有更多的资源可用,或者直到完成的合并请求释放合并令牌。

可用于分配的合并令牌数量将根据当前系统资源可用性进行调整。这个数字由系统根据在indexserver.ini文件的mergedog部分的load_balancing_func参数中配置的成本函数周期性地重新计算。默认配置为load_balancing_func = 1 + LCC * (100- cla)/100。如果需要对可用令牌数量设置硬最大值,则可以配置已配置的常量值或常量参数(例如LCC)。每个合并令牌代表一个CPU。

对于每个合并请求,执行合并所需的令牌数量由系统计算。如果系统无法确定一个值,则返回一个默认值。这个默认值可以在indexserver.ini文件的mergedog部分的token_per_table参数中配置。但是,不建议更改此值。

监控增量合并历史

关于上次系统启动以来的所有增量合并操作的信息记录在监视视图M_DELTA_MERGE_STATISTICS中。除了已完成的合并操作之外,还提供有关应用程序收到的合并提示和合并后压缩优化的信息。

您可以在SAP HANA数据库资源管理器的语句库中访问这些合并统计信息的预定义视图,也可以在SAP HANA工作室的Administration编辑器的System Information选项卡中访问。

以下几列包含可能有用的信息:

Column Description
TYPE 在这里,您可以看到合并历史记录条目的类型。可能取值如下:MERGE表示实际的增量合并操作,hint表示应用程序发送给SAP HANA的合并提示,sparse表示合并后对主存压缩的优化
MOTIVATION 这一栏标识了潜在的合并动机:AUTO、SMART、HARD或FORCE
SUCCESS 这一列取决于TYPE列中的条目。对于MERGE或SPARSE表项,它表示合并或压缩优化操作是否成功。对于HINT条目,它指示是否接受来自应用程序的合并提示。如果提示被接受(SUCCESS=TRUE),则存在MERGE类型的关联条目。如果提示被拒绝(SUCCESS=FALSE),则不会触发合并,因此没有关联的merge条目。注意即使提示被接受(SUCCESS=TRUE),这并不一定意味着后续合并成功。您必须检查合并条目的SUCCESS列。
LAST_ERROR 本专栏提供有关最近发生的错误(最常见的是2048)的错误代码的信息。详细信息在ERROR_DESCRIPTION中提供。
ERROR_DESCRIPTION 可能出现以下错误码:错误2480:正在合并的表。错误2481:队列中已经有这个表的其他智能合并请求。错误2482:增量存储为空,或者智能合并代价函数的计算表明合并是不必要的。错误2483:智能合并未激活(参数smart_merge_enabled=no)。错误2484:优化表所需的内存超过堆限制(对于失败的压缩优化操作(TYPE=SPARSE, SUCCESS=FALSE))。
PASSPORT 对于合并动机为SMART的条目,本列标识发送合并提示的应用程序(例如,由SAP HANA支持的SAP BW)。
请注意
如果索引服务器重新启动,增量合并历史记录最初将为空。系统还在表HOST_DELTA_MERGE_STATISTICS (_SYS_STATISTICS)中收集增量合并统计信息,与系统重启无关。但是,由于系统只是定期收集统计数据,因此该表可能没有最近的增量合并操作。

例子
下面是一个示例,说明如何使用合并历史记录,根据触发应用程序中的智能合并提示的设置,查找期望发生的合并。

  1. 通过执行以下SQL语句,在合并历史中查找由smart merge触发的合并:

    SELECT * FROM M_DELTA_MERGE_STATISTICS WHERE table_name = '<your_table>' AND motivation = 'SMART'
  2. 如果没有返回结果,通过执行以下语句检查应用程序是否实际发送了任何提示:
    SELECT * FROM M_DELTA_MERGE_STATISTICS WHERE type = 'HINT' AND table_name = ''

如果应用程序没有发送提示,那么系统将不会启动增量合并。但是,如果应用程序确实发送了提示,则系统仅在智能合并的条件得到满足时才执行合并。该信息在SUCCESS列中可用。系统通过评估智能合并决策代价函数来决定是否接受提示并执行合并。

  1. 如果仍然没有找到智能合并,请执行以下语句检查长期历史记录:

    SELECT * FROM _SYS_STATISTICS.HOST_DELTA_MERGE_STATISTICS WHERE table_name = '<your_table>'
跟踪

您可以在indexserver组件的数据库跟踪中激活合并相关信息的日志记录。相关的跟踪组件是mergemonitor和mergedog。我们建议使用跟踪级别INFO。

执行手动增量合并操作

例如,如果需要释放内存,可以手动触发列表的增量合并操作。

先决条件

您拥有以下特权之一:

  • 系统权限: TABLE ADMIN

  • 对表或表所在的模式执行SQL对象特权UPDATE

上下文

在某些情况下,手动触发合并操作可能是必要或有用的,例如:

  • 已发出警报,因为表超过了增量存储最大大小的阈值。

  • 你需要释放内存。对具有大增量存储的表执行增量合并操作是释放内存的一种策略。增量存储不能很好地压缩数据,并且它可能保存了一致性读取不再需要的旧版本的记录。例如,你可以使用下面的SQL语句来检索内存中增量最大的前100个存储:

    SELECT TOP 100 * from M_CS_TABLES ORDER BY MEMORY_SIZE_IN_DELTA DESC

您可以在SAP HANA studio中通过菜单命令或SQL语句手动触发列表的增量合并操作。手动执行的增量合并操作对应于硬合并。但是,如果使用SQL,还可以传递触发强制合并和仅内存合并的附加参数。

过程

以下列方式之一

执行所需的合并:

Option Description
SAP HANA studio 在Systems视图中,导航到表。
在表的上下文菜单中,选择“执行增量合并”。
选择OK。
SQL 打开SQL控制台并执行所需的语句。第一个命令是硬合并,FORCE REBUILD选项执行硬合并,即使旧的delta不能合并,旧的main不能删除。
MERGE DELTA OF '<table_name>'
MERGE DELTA OF '<table_name>' FORCE REBUILD

可选: 以以下方式之一 确认增量合并操作(SAP HANA studio):

  • 从Systems视图打开表定义,并在Runtime Information选项卡上检查相关值。

请注意
即使增量合并操作将数据从增量存储移动到主存储,增量存储的大小也不会为零。这可能是因为在进行增量合并操作时,打开的事务写入的记录被移动到新的增量存储中。此外,即使增量存储的数据容器是空的,它们仍然需要内存中的一些空间。
  • 通过打开System Information选项卡上的merge Statistics表来检查合并历史。
    SUCCESS列指示是否执行了合并操作。

提示
增量合并操作可能需要很长时间。您可以在管理编辑器的Performance Job progress选项卡中查看当前运行的增量合并操作的进度。
结果

执行增量合并操作。

请注意
与系统触发的增量合并操作不同,手动执行的增量合并操作不会随后触发表的新主存压缩优化。如果表在增量合并操作之前进行了压缩,那么之后它将使用相同的压缩策略进行压缩。如果在增量合并操作之前没有压缩它,那么之后它将保持未压缩状态。因此,在手动增量合并之后,必须手动触发压缩优化。

9、列存储的数据压缩

列存储允许有效地压缩数据。这使得SAP HANA数据库在主内存中保存数据的成本更低。它还加快了搜索和计算的速度。

列表中的数据可以有双重压缩:

  • 字典压缩  

这种默认的压缩方法应用于所有列。它涉及到将不同的列值映射到连续的数字,因此存储的不是实际值,而是通常小得多的连续数字。

  • 先进的压缩  

每个列可以使用不同的压缩方法进一步压缩,即前缀编码、运行长度编码(RLE)、聚类编码、稀疏编码和间接编码。SAP HANA数据库使用压缩算法来确定哪种压缩类型最适合于某个列。具有PAGE LOADABLE属性的列仅使用NBit算法进行压缩。

 请注意  高级压缩仅应用于列表的主存储。 由于增量存储针对写操作进行了优化,因此只应用了字典压缩。  

压缩是作为增量合并操作的一部分自动计算和优化的。如果创建空列表,则最初不会应用压缩,因为数据库无法知道哪种方法最合适。当您开始向表中插入数据并开始定期执行增量合并操作时,会自动(重新)评估和优化数据压缩。

自动压缩优化由indexserver.ini配置文件的optimize_compression部分中的活动参数确保。该参数必须为“yes”。

请注意  

如果禁用启动表的增量合并的标准方法(系统视图TABLES中的AUTO_MERGE_ON列设置为FALSE),则自动压缩优化也被隐式禁用。 即使在系统视图TABLES中将AUTO_OPTIMIZE_COMPRESSION_ON列设置为TRUE,情况也是如此。 如果表的增量合并操作由应用程序触发的智能合并控制,则有必要禁用自动合并。 有关更多信息,请参阅合并动机一节。  

压缩因子

压缩系数是指SAP HANA中未压缩的数据大小与压缩后的数据大小之比。

未压缩的数据量是一个与数据库无关的值,定义如下:标称记录大小乘以表中的记录数量。标称记录大小是所有列的数据类型大小的总和。

SAP HANA中压缩的数据量是表在SAP HANA主存中所占的数据量的总和。

例子

您可以通过执行以下语句从监视视图M_CS_TABLES中检索满载列表的信息:

select SCHEMA_NAME, TABLE_NAME, MEMORY_SIZE_IN_TOTAL from PUBLIC.M_CS_TABLES where SCHEMA_NAME='<schema>' and TABLE_NAME='<table>'

数据库实现的压缩系数取决于SAP HANA实现和所涉及的数据。

检查列表的压缩

对于列存储表,可以检查应用于表列的压缩类型以及压缩比。

先决条件

要准确地检查表的压缩状态,请确保它首先被完全加载到主存中。

过程

  1. 要检查应用于表列的压缩类型,执行以下SQL语句:

    SELECT SCHEMA_NAME, TABLE_NAME, COLUMN_NAME, COMPRESSION_TYPE,从PUBLIC加载。M_CS_COLUMNS where SCHEMA_NAME='<your_schema>' and TABLE_NAME='<your_table>'

    所选表的列与应用的压缩类型一起列出。可能取值如下:

  • DEFAULT

  • SPARSE

  • PREFIXED

  • CLUSTERED

  • INDIRECT

  • RLE

请注意
即使列没有加载到内存中,压缩类型也会显示为DEFAULT。这是因为总会有某种程度的字典压缩。但是,除非加载了列,否则数据库无法确定实际应用的压缩类型。LOADED列指示是否将列加载到内存中。
  1. 检查表列的压缩比,即列的未压缩数据大小与其在内存中的压缩数据大小之比。
    您可以在SAP HANA studio中这样做:

    a. 在Administration编辑器中,在表编辑器中打开表定义。
    b. 选择Runtime Information选项卡。
    c. 在“表的详细信息”区域中,选择“列”选项卡。
    压缩比在“主大小压缩比[%]”列中指定。

手动压缩列表

SAP HANA数据库决定要压缩列表中的哪些列,以及对每个列应用哪种压缩算法。这是合并操作的一部分。通常你不需要干涉这个过程。但是,您可以手动触发压缩。

先决条件

您拥有该表的UPDATE权限。

上下文

我们不建议您干预SAP HANA数据库应用压缩的方式。但是,如果一个表没有被压缩,而您认为它应该被压缩,那么您可以请求数据库重新评估情况。

在执行此操作之前,请考虑表可能无法压缩的原因,例如:

  1. 表很小。

  2. 表的增量存储从未与其主存储合并。

  3. 该表是使用旧版本的SAP HANA数据库创建和填充的,该数据库不能自动压缩数据。没有进行进一步的数据加载,因此也没有进行增量合并操作。

表的自动合并功能被禁用(系统视图TABLES中的AUTO_MERGE_ON列被设置为FALSE)。停用对columnstore表的自动合并也会隐式禁用自动压缩优化。即使在系统视图TABLES中将AUTO_OPTIMIZE_COMPRESSION_ON列设置为TRUE,情况也是如此。

过程

  1. 通过执行SQL语句请求数据库重新评估压缩:
    UPDATE "" WITH PARAMETERS ('OPTIMIZE_COMPRESSION'='YES')
    数据库检查表的所有列,并确定是否需要压缩它们,或者是否可以优化现有的压缩。如果是这种情况,它会使用最合适的压缩算法来压缩数据。但是,请注意以下几点:

  • 只有当表的内容自上次评估压缩以来发生了重大变化时,数据库才会重新评估压缩。

  • 即使数据库重新评估了情况,它也可能认为没有必要或无法优化压缩,因此不会改变什么。

  1. 检查表的压缩状态。

  2. 可选:如果压缩没有改变,通过执行以下SQL语句UPDATE "" WITH PARAMETERS ('OPTIMIZE_COMPRESSION'='FORCE').强制数据库重新评估压缩。
    数据库检查表的所有列,并确定是否需要压缩它们,或者是否可以优化现有的压缩。如果是这种情况,它会使用最合适的压缩算法来压缩数据。请注意,数据库可能仍然认为没有必要或无法优化压缩,因此不会改变任何东西。

  3. 检查表的压缩状态。

参考

HANA managing tables至2.0SPS07 Release 主要来自其中内容的翻译和整理


原文作者:数据库杂记;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2019-04-22

  • 博文量
    276
  • 访问量
    160349