用于在另一个Oracle包中调用过程/函数的开销

时间:2009-11-09 15:03:12

标签: oracle plsql package

我们正在讨论将通用功能/程序放在单独的包中或在每个包中使用本地副本对性能的影响。

我的想法是,在包中使用公共代码会更清晰,但其他人则担心性能开销。

思想/经验?

3 个答案:

答案 0 :(得分:7)

将它放在一个地方,并从许多人那里调用它 - 这是基本代码的重用。从另一个包调用一个包的任何开销都是微不足道的。如果他们仍然怀疑它,让他们展示性能差异。

答案 1 :(得分:5)

通过证明性能开销,担忧者可以完全自由地证明其关注点的有效性。这应该是微不足道的。

同时,他们应该考虑在多个地方重复代码的内存使用和维护开销。

公共代码放在一个包中。

答案 2 :(得分:1)

除非您通过DB链接调用位于不同数据库上的程序包中的过程,否则在另一个程序包中调用过程的开销可以忽略不计。

存在一些性能问题以及内存问题,但这些问题很少发生。此外,他们属于“甲骨文黑魔法”类别。例如,选中this link。如果您能清楚地了解这是什么,请认为自己是一位成熟的Oracle专业人士。如果不是 - 别担心,因为它真的是硬核。

然而,您应该考虑的是依赖性问题。 Oracle软件包由两部分组成: spec body Spec 是一个标头,其中声明了 public 过程和函数(即在包外可见)。 Body 是他们的实现。 虽然密切相关,但它们是2个单独的数据库对象。

Oracle使用包状态来指示包是VALID还是INVALID。如果包变得无效,那么所有其他包 依赖它也变得无效。 例如,如果您编程调用程序包A中的过程,该过程调用程序包B中的过程,则表示这意味着 你在程序包A上编程依赖,而程序包A依赖于程序包B.在Oracle中,这种关系是可传递的,这意味着 你的程序取决于软件包B.因此,如果软件包B坏了,你的程序也会被制动(终止时会出错)。

这应该是显而易见的。但不太明显的是,Oracle还通过软件包规范跟踪编译期间的依赖关系。

让我们假设您的包A和包B的规格和主体都已成功编译并且有效。 然后你去改变包装B的包装体。因为你只改变了身体,而不是规格, Oracle认为调用包B的方式没有改变,也没有做任何事情。

但如果与身体一起更改包B的规格,那么Oracle怀疑你可能已经改变了一些 过程的参数或类似的东西,并将整个链标记为无效(即包B和A以及您的程序)。 请注意,Oracle不会检查规范是否真的发生了变化,它只是检查时间戳。因此,只需重新制定规范就可以使一切无效。

如果发生失效,下次运行程序时它将失败。 但是如果你再次运行它,Oracle将自动重新编译所有内容并成功执行它。

我知道这令人困惑。这是甲骨文。不要试图围绕它包住你的大脑。 你只需记住几件事:

  • 尽可能避免复杂的包间依赖关系。如果有一件事取决于另一件事,这取决于另外一件事,等等, 那么通过重新编译一个数据库对象使一切无效的可能性非常高。 最糟糕的情况之一是“循环”依赖,当包A调用包B中的过程,而包B调用包A中的过程时。 在这种情况下,几乎不可能在不制动另一个的情况下编译一个。

  • 将包规格和包装正文保存在单独的源文件中。如果您只需更换机身,请不要触摸规格!