Hi,
I'm writing a PL/SQL program that isn't performing so well, and I was wondering if anyone knows of any good references where I can learn more about the machine model PL/SQL is operating under. If not, my specific questions are:
1) Are parameters passed by value or by reference? (i.e. if I pass a big VARCHAR2 does it do a memcpy of the whole thing?)
2) Same thing for return values...
3) How do you typically access big chunks of memory from different points in a PL/SQL program? In C I would just pass around and return a pointer to it, but I don't see an analogous construct here. From experimentation, the REF facility seems very inflexible -- I would like to create a REF to an arbitrary variable in my program, like you would with a pointer in C, but all the examples I've seen assign REF vars their values out of a table.
4) What's the closest I can get to a dynamically allocated array that I'd like to pass around my program? I was using pipelined tables, but they are incredibly slow. Now I'm using a VARRAY but it scares me because it has a max size.
Thanks! Sorry for all the questions, but I find it's very hard to guess at what's happening under the surface here.
PeteYou could start with the Oracle PL/SQL Reference:
http://download-west.oracle.com/docs/cd/B10501_01/appdev.920/a96624/toc.htm
I can tell you that IN parameters are generally passed by value, but there is a NOCOPY option to use a reference instead, which is normally used only for passing large collections as IN parameters.
I would use an "associative array" (aka index-by table) rather than a VARRAY. These do not have a declared size like a VARRAY. If you declare the array in a package specification, it can be accessed from anywhere in your code as package_name.array_name.
PL/SQL is mainly intended as a language for working closely with the database, and in most cases any performance problems come from badly tuned SQL and database designs rather than from the PL/SQL itself. For computationally intensive processes where you spend more time crunching arrays in memory than querying the database, Pro*C may be a better bet. (Or maybe your code can be redesigned to make use of SQL set-based processing rather than array-crunching).|||Well my experience / understanding is this...
- IN parameters are passed by reference. NOCOPY does not apply.
- IN OUT and OUT parameters are passed by value / copy unless NOCOPY directive is used in which case they are passed by reference (provided NOCOPY restrictions do not apply).
- The RETURN value of a function is copied to the variable to which it is assigned.
All of which means the most efficient way to pass a large variable is in IN OUT or OUT mode using NOCOPY (provided NOCOPY restrictions do not apply!). You might also consider holding the variable as a package global variable if copying it around is causing a problem (see usual reservations about global variables).|||Thanks, Padders, I got that exactly the wrong way round! Should have read the manual before opening my gob.
(FWIW, my incorrect thought process was: for an IN parameter, you only need the value; for an IN OUT or OUT parameter you need a reference so that you know where to write the changes. Seemed so "obvious" I didn't bother to check it!)
No comments:
Post a Comment