optimizer_index_caching
optimizer_index_caching初始化参数用于指定在in-list迭代操作和嵌套循环连接的执行期间预期在缓冲区中缓存的索引块总量(按百分比算)。应该注意到,这个初始化参数的值仅被查询优化器用来调整它的估算值。
换句话说,它并不指定每个索引应该由数据库引擎缓存多少。合法的值范围是从0到100。默认值是0。比0大的值降低in-list迭代操作和嵌套循环连接的内部循环执行的索引扫描的成本。正因如此,optimizer_index_caching参数被用来增加这些操作的使用率。
公式9-4展示了将修正应用于前一小节呈现的索引范围扫描成本公式(公式9-3)后的结果。
公式9-4 基于索引范围扫描的表访问的I/O成本
这个初始化参数拥有与上一节中描述的 optimizer_index_cost_adj 初始化参数类似的缺点。虽然如此,它的影响普遍较小主要因为两个原因。首先,它只用于嵌套循环和in-list迭代操作。其次,它对于用于索引范围扫描的成本公式(公式9-4)的群集因子部分没有影响。
因为群集因子经常是成本公式中最大的因子,所以这个初始化参数不太可能导致错误的决定。总之,这个初始化参数对于查询优化器的影响比optimizer_index_cost_adj 初始化参数要小。也就是说,默认值通常工作良好。
optimizer_index_caching 初始化参数是动态的,并且可以在实例和会话级别修改。在12.1版本的多租户环境下,也可以在pdb级别设置它。
optimizer_secure_view_merging
optimizer_secure_view_merging初始化参数可以用来控制类似视图合并和谓词迁移之类的查询转换。可以将它设置为FALSE或TRUE。默认值是TRUE。
Ø FALSE 允许查询优化器无需检查应用查询变换是否会导致安全问题就这样做。
Ø TRUE 允许查询优化器在只有应用查询变换不会导致安全问题时才这样做。
注意 因为名称的原因,你可能会认为optimizer_secure_view_merging初始化参数只与视图合并有关。但是,它控制着所有可能导致安全问题的查询变换。用这个名称的原因很简单:最初实现它时,它只能控制视图合并。
要理解这个初始化参数的影响,我们来看一个例子,该例子演示了为何从安全的角度来看视图合并可能是危险的(完整示例参见optimizer_secure_view_merging.sql脚本)。
假定你有一张很简单的表,该表拥有一个主键和另外两个列:
CREATE TABLE t (
id
NUMBER(10) PRIMARY KEY,
class NUMBER(10),
pad
VARCHAR2(10)
);
基于安全的原因,你想要通过下面的视图来提供对这张表的访问。注意通过函数应用的过滤条件来部分地显示这张表的内容。这个函数是如何实现的以及它到底做什么不重要:
CREATE OR REPLACE VIEW v AS
SELECT *
FROM t
WHERE f(class) = 1;
举个例子,一个有权使用这个视图的用户创建了下面的PL/SQL函数。如你所见,它会直接通过对dbms_output包的调用来显示输入参数的值:
CREATE OR REPLACE FUNCTION spy (id IN
NUMBER, pad IN VARCHAR2) RETURN NUMBER AS
BEGIN
dbms_output.put_line(' pad='||pad);
RETURN 1;
END;
/
将optimizer_secure_view_merging初始化参数设置为FALSE,可以运行两个测试查询。两个查询都只会返回允许用户查看的那部分值。然而,在第二个查询中,由于视图合并,在查询中添加的函数的执行要早于对函数实施的安全检查。因此,你能够看到你本不能够访问的数据:
SELECT id, pad
FROM v
WHERE id BETWEEN 1 AND 5;
SELECT id, pad
FROM v
WHERE id BETWEEN 1 AND 5
AND spy(id, pad) = 1;
将optimizer_secure_view_merging设置为TRUE,第二个查询返回如下的输出结果。你可以看到,函数和查询显示了相同的数据:
SELECT id, pad
FROM v
WHERE id BETWEEN 1 AND 5
AND spy(id, pad) = 1;
注意,如果视图的所有者和查询的发起者是同一个用户,optimizer_secure_view_merging初始化参数就会被忽略(因为,阻止一个用户查看他已经可以直接通过查询视图所引用的表来读取的数据,这是毫无意义的)。
一个类似的例子,但是用来展示谓词迁移应用于虚拟私有数据库(VPD)谓词上时的影响,可以在optimizer_secure_view_merging_vpd.sql脚本中找到。
概括起来,通过将optimizer_secure_view_merging初始化参数设置为TRUE,查询优化器检查查询变换是否会导致安全问题。如果会导致这种问题,则查询变换不会被执行,此时性能表现可能不是最优的。基于这个原因,如果你没有将视图也没有将VPD用作安全用途,我建议你将optimizer_secure_view_merging初始化参数设置为FALSE。
optimizer_secure_view_merging初始化参数是动态的,并且可以在实例级别修改。在12.1版本的多租户环境下,也可以在PDB级别进行设置。但是如果用户拥有 MERGE VIEW 对象权限或者 MERGE ANY VIEW 系统权限,则不受这个初始化参数施加的限制条件影响。要知道,默认的dba角色提供 MERGE ANY VIEW 系统权限。