Jus*_*ave 27
从性能的角度来看,差异比OMG Ponies所暗示的蒂姆霍尔提示要复杂得多.我相信这个提示是对一个较大的部分的介绍,该部分已经被网络摘录 - 我希望Tim继续在书中创造大部分(如果不是全部的话).此外,整个讨论取决于您使用的Oracle版本.我相信这对于10.2,11.1和11.2是正确的,但如果你开始回到旧版本,肯定存在差异.
首先,提示中的特定示例是不切实际的.我从未见过有人使用显式游标而不是SELECT INTO编写单行提取代码.因此,SELECT INTO更高效的事实具有非常有限的实际重要性.如果我们讨论循环,我们感兴趣的性能是获取许多行的成本是多少.这就是复杂性开始出现的地方.
Oracle引入了从游标到10.1中的PL/SQL集合进行BULK COLLECT数据收集的能力.这是一种将数据从SQL引擎传递到PL/SQL集合的更有效方法,因为它允许您通过一次获取多行来最小化上下文移位.对这些集合的后续操作更有效,因为您的代码可以保留在PL/SQL引擎中.
但是,为了最大限度地利用BULK COLLECT语法,您通常必须使用显式游标,因为这样您可以填充PL/SQL集合,然后使用FORALL语法将数据写回数据库(在合理的假设是,如果你在游标中获取一堆数据,很有可能你正在进行某种操作并在某处保存操纵数据).如果在FOR循环中使用隐式游标,正如OMG Ponies正确指出的那样,Oracle将在幕后进行BULK COLLECT以使得获取数据的成本更低.但是您的代码将逐行插入和更新,因为数据不在集合中.
通常,假设您使用的是10.2或更高版本并且您的代码正在获取数据并将其写回数据库,
最快的
最慢
另一方面,使用隐式游标可以在重构旧代码或学习新功能时使用批量操作获得很少的前期成本.如果您的大多数PL/SQL开发都是由主要语言不同或者不一定能跟上新语言特性的开发人员完成的,那么FOR循环将比使用全部的显式游标代码更容易理解和维护.新的BULK COLLECT功能.当Oracle在未来引入新的优化时,隐式游标代码更有可能自动获得好处,而显式代码可能需要一些手动返工.
当然,当您对性能进行故障排除时,您真正关心循环代码的不同变体可能会有多快,您通常会考虑将更多逻辑转移到纯SQL中并完全抛弃循环代码.