上接IM 5.2。本章为IM系列第五章 使用In-Memory表达式优化查询第三部分IM表达式如何工作。
要将表达式标识为IM表达式的候选,数据库将查询ESS。优化器使用ESS来维护有关特定表的表达式计算的统计信息。
本节包含以下主题:
IME_CAPTURE_EXPRESSIONS
过程,数据库都会查询ESS,并在指定的时间范围内标识20个最常访问(“最热”)表达式。IM表达式基础架构负责在IM列存储中计算和填充IM表达式,IM虚拟列和任何其他有用的内部计算的结果。这些优化主要有利于分析查询。
填充结果可以包括在项目,扫描或连接表达式中使用的列的函数评估。在查询评估期间,IM列存储可以根据SQL运行时引擎评估的表达式自动缓存内部计算。
虚拟列
除了填充IM表达式,IM列存储可以填充In-Memory虚拟列。底层机制是相同的:IM表达式是虚拟列。但是,IM虚拟列是用户创建和公开的,而IM表达式是数据库创建和隐藏的。
静态表达式:二进制JSON列
IM表达式基础架构支持动态表达式(IM表达式和虚拟列)和静态表达式。从OracleDatabase 12c Release 2(12.2)开始,IM列存储支持二进制JSON格式,其性能优于基于行的JSON文本存储。数据库使用IM表达式基础架构将JSON文本列的高效二进制表示形式作为虚拟列加载。查询访问实际的JSON数据,但使用优化的虚拟列来加速访问。
Oracle数据库支持多个JSON函数:JSON_TABLE
,JSON_VALUE
和JSON_EXISTS
。INMEMORY_EXPRESSIONS_USAGE
初始化参数控制动态表达式和静态表达式的行为。
无论何时调用IME_CAPTURE_EXPRESSIONS
过程,数据库都会查询ESS,并在指定的时间范围内标识20个最常访问(“最热”)表达式。
时间范围是过去24小时,或数据库创建之后。数据库仅考虑在IM列存储中至少部分填充的表上的表达式。
数据库将20个最热表达式添加到其各自的表中作为隐藏的SYS_IME
虚拟列,并应用默认的INMEMORY
列压缩子句。如果在上次调用期间添加的任何SYS_IME
列不再在最新的表达式列表中,则数据库将其属性更改为NO INMEMORY
。
图5-1捕获SYS_IME列
表的SYS_IME
列的最大数量为50,而不管属性是否为INMEMORY
。表达到50表达式限制后,数据库不会添加新的SYS_IME
列。要允许新表达式,必须使用DBMS_INMEMORY.IME_DROP_EXPRESSIONS
或DBMS_INMEMORY_ADMIN.IME_DROP_ALL_EXPRESSIONS
过程删除SYS_IME
列。
SYS_IME
虚拟列和用户定义的虚拟列都计入表的1000列限制。例如,如果表中包含980个非虚拟(磁盘)列,那么您只能添加20个虚拟列。
ESS是由优化器维护的用于存储关于表达式评估的统计信息的存储库。
对于每个表,ESS维护表达式统计信息,例如执行次数和评估成本。在评估谓词时,Oracle数据库会跟踪并提供关于评估计数和表达式的动态成本的运行时反馈。基于ESS统计信息,如果特定表达式是IM表达式,则数据库可能会决定查询将执行得更好。
注:
在特定表的ESS中缓存的表达式仅涉及此表的列。当Oracle数据库将确定性PL / SQL函数标识为IM表达式的候选项时,此规则尤为重要。
图5-2 ESS和IM表达式
在该图中,ESS已经在employees
表中确定了两个常用的表达式:ROUND(salary*12/52,2)
和12*(salary*NVL(commission_pct,0)+salary)
。当数据库填充IM列存储中的employees
时,两个IMCU存储列数据。每个IMCU与其唯一的IMEU相关联,它包含IMCU中行的两个常用表达式的派生值。
不是每个表达式都是IM表达式的候选者。数据库仅考虑将被频繁访问的表达式。因为IM表达式被实现为隐藏的虚拟列,它们还必须满足虚拟列的限制。
虽然IM列存储是ESS的客户端,但ESS独立于数据库内存功能。其他客户端也可以使用ESS统计信息,包括优化器本身。
在内存协调器进程(IMCO)的指导下,空间管理工作进程(Wnnn)会自动将IM表达式加载到IMEU中。
数据库会增加每个内存中压缩单元(IMCU)的填充或重新填充任务,其中包含要填充的用户定义或IM表达式的哪些虚拟列的信息。决定取决于INMEMORY_EXPRESSION_USAGE
和INMEMORY_VIRTUAL_COLUMNS
初始化参数的设置。
注:
DBMS_INMEMORY.IME_CAPTURE_EXPRESSIONS
过程会将检测到的表达式自动添加为隐藏的虚拟列。
Wnnn进程创建IMCU。要创建IMEU,进程将执行以下附加步骤:
1. 创建表达式值
2. 将值转换为柱状格式,并将其压缩为内存表达式单位(IMEU)
3. 将每个IMEU链接到其相关联的IMCU
注:
随着IMEU中存储的表达式数量的增加,工作进程可能会消耗更多的CPU来计算表达式值。这种开销可能会增加填充时间。
对于任何行,物理列位于IMCU中,虚拟列驻留在关联的IMEU中。 IMEU是只读和柱状的,就像IMCU一样。
因为IMEU是为特定INMEMORY
段创建的IMCU的逻辑扩展,因此默认情况下,它们继承INMEMORY
子句和Oracle Real Applications Cluster(Oracle RAC)属性(如DISTRIBUTE
和DUPLICATE
)。 IMEU与一个IMCU相关联。然而,一个IMCU可能有多个IMEU。数据库将IMEU作为单独的结构进行管理,使其更易于添加和删除。
注:
IMEU还包含用户创建的IN虚拟列。
如果源数据更改,则数据库会在重新填充期间更改IM表达式中的派生数据。例如,如果事务更新表中的100个工资值,则空间管理工作进程(Wnnn)将自动更新从这100个更改的值派生的所有IM表达式值。数据库将IMCU及其相关联的IMEU重新填充,而不是首先重新填充所有IMCU,然后重新填充所有IMEU。在IMCU重新填补期间,IMCU仍可用于查询。
未完待续。
以下是IM系列内容:
第一章 Oracle Database In-Memory 相关概念(IM-1.1)
第一章 Oracle Database In-Memory 相关概念(续)(IM-1.2)
第二章 Oracle Database In-Memory 体系结构(上) (IM-2.1)
第二章 IM 体系结构:CPU架构:SIMD向量处理(IM-2.3)
第四章 为In-Memory 启用填充对象(IM-4.1 第一部分)
第四章 为In-Memory 启用填充对象(IM-4.2 第二部分)
第四章 为IM 启用填充对象之启用和禁用列(IM-4.3 第三部分)
第四章 为IM 启用填充对象之在NO INMEMORY表上指定INMEMORY列属性:示例(IM-4.4 第四部分)
第四章 为IM 启用填充对象之启用和禁用表空间的IM列存储(IM 4.5)
第四章 为IM 启用填充对象之强制填充In-Memory对象:教程(IM 4.7)
第四章 为IM 启用填充对象之为IM列存储启用ADO(IM 4.8)
第五章 使用In-Memory表达式优化查询(IM 5.1)
山东Oracle用户组(Shandong Oracle User Group),简称:SDOUG,是一个充满朝气、年轻的非营利性组织,旨在为济南及周边地区技术爱好者提供一个交流平台。SDOUG会不定期组织线下技术分享活动,促进本地区及周边IT技术的发展、帮助技术爱好者提高自己。分享技术、分享快乐,SDOUG在路上。