从性能的角度来看,差异比
Tim Hall tip that OMG Ponies linked to将会更为复杂.我相信这个提示是介绍一个更大的部分,已经被网络摘录 – 我希望蒂姆继续在这本书中做出最大的贡献.此外,这整个讨论取决于您使用的Oracle版本.我相信这对10.2,11.1和11.2是正确的,但是如果你开始回到旧版本,那肯定有差异.
提示中的一个特别例子首先是相当不切实际的.我从来没有看到任何人使用显式光标而不是SELECT INTO编码单行提取.因此,SELECT INTO更有效率的事实是非常有限的实际重要性.如果我们正在讨论循环,我们感兴趣的性能是获取许多行是多么昂贵.这就是复杂性开始的地方.
Oracle引入了一种将游标中的数据从BULK收集到10.1中的PL / sql集合的功能.这是从sql引擎获取数据到PL / sql集合的一种更有效的方式,因为它允许您通过一次提取多行来最小化上下文偏移.对这些集合的后续操作更有效,因为您的代码可以保留在PL / sql引擎中.
为了最大限度地利用BULK COLLECT语法,您通常必须使用显式游标,因为您可以填充PL / sql集合,然后使用FORALL语法将数据写回数据库(在合理的假设是,如果您在光标中获取一堆数据,则很有可能您正在进行某种操作并将操纵数据保存在某个地方.如果在FOR循环中使用隐式游标,OMG Ponies正确指出,Oracle将在幕后进行大量收集,以使数据获取更为便宜.但是您的代码将逐行插入和更新,因为数据不在集合中.显式游标还提供了明确设置LIMIT的机会,可以在FOR循环中为隐式游标提高默认值100的性能.
一般来说,假设你是10.2或更高版本,并且您的代码正在获取数据并将其写回数据库,
最快的
>将BULK COLLECT的显式光标移入本地集合(具有相应的LIMIT)并使用FORALL将其写回数据库.
>为幕后做一个BULK COLLECT的隐式游标以及单行写回数据库.
>没有做BULK COLLECT而不是利用PL / sql集合的显式游标.
最慢
另一方面,使用隐式光标可以让您在重构旧代码或学习新功能时使用批量操作的前期成本很低.如果大多数PL / sql开发是由主要语言是别的东西或者不一定跟上新语言功能的开发人员完成的,那么FOR循环将比使用所有这些功能的显式游标代码更容易理解和维护新的BULK COLLECT功能.而当Oracle将来会引入新的优化时,隐式游标代码可能会自动获得优势,而显式代码可能需要一些手工返工.
当然,当您将性能进行故障排除时,您真的关心循环代码的不同变体的速度有多快,您通常会考虑将更多的逻辑转换为纯sql并完全循环代码.