views:

365

answers:

3

We're discussing the performance impact of putting a common function/procedure in a separate package or using a local copy in each package.

My thinking is that it would be cleaner to have the common code in a package, but others worry about the performance overhead.

Thoughts/experiences?

+6  A: 

Put it in one place and call it from many - that's basic code re-use. Any overhead in calling one package from another will be minuscule. If they still doubt it, get them to demonstrate the performance difference.

Tony Andrews
+5  A: 

The worriers are perfectly at liberty to prove the validity of their concerns by demonstrating a performance overhead. that ought to be trivial.

Meanwhile they should consider the memory usage and maintenance overhead in repeating code in multiple places.

Common code goes in one package.

David Aldridge
A: 

Unless you are calling a procedure in a package situated on a different data base over a DB link, the overhead of calling a procedure in another package is negligible.

There are some performance concerns, as well as memory concerns, but they are rare and far between. Besides, they fall into "Oracle black magic" category. For example, check this link. If you can clearly understand what that is about, consider yourself an accomplished Oracle professional. If not - don't worry, because it's really hardcore stuff.

What you should consider, however, is the question of dependencies. Oracle package consists of 2 parts: spec and body: Spec is a header, where public procedures and functions (that is, visible outside the package) are declared. Body is their implementation. Although closely connected, they are 2 separate database objects.

Oracle uses package status to indicate if the package is VALID or INVALID. If a package becomes invalid, then all the other packages that depend on it become invalid too. For example, If you programme calls a procedure in package A, which calls a procedure in package B, that means that you programme depends on package A, and package A depends on package B. In Oracle this relation is transitive and that means that your programme depends on package B. Hence, if package B is broken, your programme also brakes (terminates with error).

That should be obvious. But less obvious is that Oracle also tracks dependencies during the compile time via package specs.

Let's assume that the specs and bodies for both of your package A and package B are successfully compiled and valid. Then you go and make a change to the package body of package B. Because you only changed the body, but not the spec, Oracle assumes that the way package B is called have not changed and doesn't do anything.

But if along with the body you change the package B's spec, then Oracle suspects that you might have changed some procedure's parameters or something like that, and marks the whole chain as invalid (that is, package B and A and your programme). Please note that Oracle doesn't check if the spec is really changed, it just checks the timestemp. So, it's enough just to recomplie the spec to invalidate everything.

If invalidation happens, next time you run you programme it will fail. But if you run it one more time after that, Oracle will recompile everything automatically and execute it successfully.

I know it's confusing. That's Oracle. Don't try to wrap your brains too much around it. You only need to remember a couple of things:

  • Avoid complex inter-package dependencies if possible. If one thing depends on the other thing, which depends on one more thing and so on, then the probability of invalidating everything by recompiling just one database object is extremely high. One of the worst cases is "circular" dependencies, when package A calls a procedure in package B, and package B calls procedure in package A. It that case it is almost impossible to compile one without braking another.

  • Keep package spec and package body in separate source files. And if you need to change the body only, don't touch the spec!

Sergey Stadnik