我认为这个问题可以大致回答。在调整此类查询的性能时,您需要考虑许多事项:
解析时间
建立该语句的执行计划需要多长时间?如果查询第一次运行缓慢,而之后每次运行都很快,则解析时间就是一个问题。我假设查询中没有变化的常量。如果没有,请使用绑定变量或作为最后的手段使用动态绑定变量,但自动引入绑定变量可能是一个坏主意,请参阅“alter session setcursor_sharing=similar”。
特别是对于旧版本和许多连接(Oracle 8 在解析具有超过 6 个相似标识连接的语句时确实很糟糕......)解析时间可能会很昂贵。 Oracle 11 通常会在考虑多个执行计划后停止,从而缩短解析时间。在 Oracle 11 上,解析时间仍然可能是一个问题,特别是对于 union/union all。
此外,在此查询中您使用 ANSI 样式连接。请注意,当使用更优雅的 ANSI 样式与复杂语句连接时,Oracle 11 存在一些性能缺陷。因此对于自动生成的语句我推荐Oracle风格(c(+)=d),对于需要维护的语句你需要研究它是否真的是一个问题。
当解析时间是一个问题时,我建议使用 /*+ordered*/ 这样的提示作为起点。这样可以确保您的连接顺序使得临时生成的数据量尽可能少,并且存在正确的索引。
执行时间处理时间
在执行过程中,Oracle执行执行计划。与其他数据库平台相比,Oracle 在这方面确实非常高效。但如果执行计划很糟糕,那么执行就需要时间。在您的问题中,您讨论是否要预先加入所有内容。
一般来说,最好总是从完全标准化的模型开始。在完全标准化的模型中,数据仅存储一次。因此,当有效规划查询时,处理的数据量最少。这假设 Oracle 服务器有足够的内存来缓存全部或大部分数据,因为连接策略有时需要内存中的大量工作空间以及已经从磁盘获取的数据。
当性能不足时,我会首先引入提示,但保留标准化模型。始终尝试使中间步骤期间适合输出的数据量尽可能小。当它确实不起作用时,您可能会使用派生表,但我发现这通常是开发技能薄弱的标志。
在这一切中,我假设启动执行计划的表之一具有较大的数据量,而另一个表较小,可能小一点或小很多。如果没有,您正在运行“Wiebertje”查询(我没有它的另一个名称,它是荷兰糖果的形状)。那么请阅读第 9 页及后续内容2006年会议演讲 http://www.invantive.com/nl/doc/effective-performance-tuning-oracle-applications.pdf
获取时间
在周期结束时,Oracle 在某个时刻开始发回数据。特别是体积可能会大大增加传输全部内容所需的时间。应用程序获取所有内容但仅显示前 50 行的情况并不少见。请引入窗口或“获取显示的水印+常量”以减少获取时间。您可能需要在语句或会话中引入诸如 /*+first_rows */ 之类的提示以供交互使用。