在使用Oracle数据库的过程中,视图作为数据库对象存在。因此,创建这样的视图后,可以通过工具或者数据字典查看视图的相关信息。视图来源于表,对视图数据的所有修改最终都会反映到视图的基表中。这些修改必须服从基表的完整性约束,同时也会触发定义在基表上的触发器。Oracle的视图分为两种:简单视图和复杂视图。简单视图是从单个表中获取数据,不包括函数和数据组。复杂视图是指包含聚合函数、分析函数、用户自定义函数、多表关联、子查询等的视图定义,在这类视图的某些条件下,优化器无法将视图外的谓词条件推送到基层视图中的表,即使在基表的列上创建了索引,也无法使用该索引。本文将针对此类视图提出一种优化方案,可以显着提升此类视图的性能,而且表的数据量越大,查询数据越少,性能提升越明显。接下来,本文在实际操作的基础上,简要说明影响谓词推送的因素以及如何对其进行优化。影响谓词推送的因素本文的实验环境是Oracle11.2.0.4版本的数据库。作者通过反复测试发现,如果查询语句中存在以下两种情况,优化器会阻止视图谓词条件被推送到基表:1、视图中的查询包含ROWNUM伪列;第二个是视图包含分析函数(例如ROW_NUMBER()OVER(...))。对于其他影响predicatepush的情况,优化方法与此方法类似。此外,11.2.0.4之前的Oracle版本可能存在影响谓词推送的其他条件。优化方法如果可以将这类视图中常用的谓词条件直接写到视图中,并且写成动态的,同时从大到小选择常用的查询列来创建复合索引,那么优化器可以尽可能直接使用索引。获取数据,然后进行过滤计算等操作,达到优化的目的。具体操作步骤如下:(1)创建辅助包,创建两个函数。实际情况中,如果同时传入多个条件,可以自行扩展包中的方法。每个条件需要添加两个方法。(2)修改视图定义,将谓词条件写入基表条件,重新编译视图。性能对比下面通过具体的例子来说明如何优化复杂视图。通过对比原始视图和优化后的视图,可以看出优化后的视图的执行计划成本从349降低到86,优化效果非常明显。表中红框部分需要特别注意。优化前视图查询的执行计划是全表扫描,执行效率低。优化视图查询的执行计划是索引范围扫描。通过索引直接检索需要访问的数据,再进行后续处理,性能较优化前有很大提升。需要指出的是,这种方法只在访问视图中的少量数据时有效,这种方法不适合访问大量数据。表4.1优化前的视图定义、查询语句和执行计划表4.2优化后的视图定义、查询语句和执行计划通过以上分析对比,可以明显看出优化后的视图可以使用索引,性能有了明显的提升.综上所述,对于复杂查询的优化思路应该是:如果在视图中访问的数据量很小,尽量先通过索引检索出要处理的数据,再进行后续处理。该方法的前提是复杂视图使用各种常规优化方法(如添加索引、添加提示等)均无效。但是,这种方法也有一定的缺点,即与其他优化方法相比,这种方法需要做更多的前期工作,如建立辅助包、修改和重新编译原始视图等。另外,需要测试优化前后的查询结果是否一致。在查询之前,需要调用辅助包将查询条件传递到视图中,但优化视图不需要添加查询条件。
