Skip to Main Content

Breadcrumb

Question and Answer

Tom Kyte

Thanks for the question, jery.

Asked: June 13, 2002 - 1:52 pm UTC

Last updated: January 28, 2009 - 7:51 am UTC

Version: 9

Viewed 10K+ times! This question is

You Asked

Good morning Tom,

Could you please give us a hint on the performance that can be reached compiling a procedure into native code, c for example.

Thanks.



and Tom said...

2x is a good maximum.
0x is a good minimum.

Somewhere in between is where you will generally fall.

It depends 100% on the code itself. Lots of numeric computations -- no sql, just plsql processing. 2x is possible (maybe even a little more).

Lots of SQL, most of the time is in SQL -- 0x. The sql won't run any faster, just the compute intensive PLSQL.

Rating

  (72 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

A reader, June 13, 2002 - 2:49 pm UTC

Thanks.

clarification, please...

George, June 13, 2002 - 4:12 pm UTC

are you saying that an SQL query that is encapsulated
in a C program will run at virtually the same speed,

but that if I convert a PLSQL program - say a cursor
loop that summarizes the data - to C, moving the loop
constructs to C, that the C program will run up to 2x?

Or are you saying something completely different?

Tom Kyte
June 13, 2002 - 4:35 pm UTC

I'm saying something totally different.

We are talking about ncomp'ed PLSQL (natively compiled plsql).  In 9i, when you compile a procedure, you can "ncomp" it.  

Normally, PLSQL is processed like this:

you write it -> we compile it into p-code -> you run it -> we interpret the p-code

With ncomping it is like this:

you write it -> we turn it INTO c -> we compile that into a .obj or .o file ->
  we link that into the database kernel -> you run it -> we just call a subroutine


It is like using a JIT compiler with java for example but this is a WAT compiler (way ahead of time).

Here is a quick and dirty example I use:

ops$tkyte@ORA9I.WORLD> @demo021   
=================================================================


make sure the settings are setup right for NCOMP'ed plsql


ops$tkyte@ORA9I.WORLD> 
ops$tkyte@ORA9I.WORLD> alter system set plsql_native_make_utility = 'make';

System altered.

ops$tkyte@ORA9I.WORLD> alter system set plsql_native_make_file_name = '/export/home/oracle9i/plsql/spnc_makefile.mk';

System altered.

ops$tkyte@ORA9I.WORLD> alter session set plsql_compiler_flags = 'INTERPRETED';

Session altered.

ops$tkyte@ORA9I.WORLD> 
ops$tkyte@ORA9I.WORLD> 
ops$tkyte@ORA9I.WORLD> set echo off
Enter to continue

=================================================================

we'll compile an interpreted one (default) first


ops$tkyte@ORA9I.WORLD> 
ops$tkyte@ORA9I.WORLD> alter session set plsql_compiler_flags = 'INTERPRETED';

Session altered.

ops$tkyte@ORA9I.WORLD> 
ops$tkyte@ORA9I.WORLD> create or replace
  2  function factorial_interpreted( p_n in number ) return number
  3  is
  4  begin
  5      if ( p_n = 1 )
  6      then
  7          return 1;
  8      else
  9          return factorial_interpreted( p_n-1 ) * p_n;
 10      end if;
 11  end;
 12  /

Function created.

ops$tkyte@ORA9I.WORLD> 
ops$tkyte@ORA9I.WORLD> set echo off
Enter to continue

=================================================================

and now NATIVE (too easy)


ops$tkyte@ORA9I.WORLD> 
ops$tkyte@ORA9I.WORLD> 
ops$tkyte@ORA9I.WORLD> alter session set plsql_compiler_flags = 'NATIVE';

Session altered.

ops$tkyte@ORA9I.WORLD> 
ops$tkyte@ORA9I.WORLD> create or replace
  2  function factorial_native( p_n in number ) return number
  3  is
  4  begin
  5      if ( p_n = 1 )
  6      then
  7          return 1;
  8      else
  9          return factorial_native( p_n-1 ) * p_n;
 10      end if;
 11  end;
 12  /


Function created.

ops$tkyte@ORA9I.WORLD> 
ops$tkyte@ORA9I.WORLD> set echo off
Enter to continue
=================================================================

and the race is on...


ops$tkyte@ORA9I.WORLD> 
ops$tkyte@ORA9I.WORLD> 
ops$tkyte@ORA9I.WORLD> alter session set plsql_compiler_flags = 'INTERPRETED';

Session altered.

ops$tkyte@ORA9I.WORLD> 
ops$tkyte@ORA9I.WORLD> declare
  2      l_start number;
  3      l_n     number;
  4  begin
  5      l_start := dbms_utility.get_time;
  6      for i in 1 .. 1000
  7      loop
  8          l_n := factorial_interpreted( 50 );
  9      end loop;
 10      dbms_output.put_line( (dbms_utility.get_time-l_start) ||
 11          ' hsecs...' || l_n );
 12  
 13      l_start := dbms_utility.get_time;
 14      for i in 1 .. 1000
 15      loop
 16          l_n := factorial_native( 50 );
 17      end loop;
 18      dbms_output.put_line( (dbms_utility.get_time-l_start) ||
 19          ' hsecs...' || l_n );
 20  end;
 21  /
45 hsecs...30414093201713378043612608166064768844300000000000000000000000000
27 hsecs...30414093201713378043612608166064768844300000000000000000000000000

PL/SQL procedure successfully completed.

ops$tkyte@ORA9I.WORLD> /
46 hsecs...30414093201713378043612608166064768844300000000000000000000000000
26 hsecs...30414093201713378043612608166064768844300000000000000000000000000

PL/SQL procedure successfully completed.

ops$tkyte@ORA9I.WORLD> 

 

.obj , .o, .pcode

A reader, June 13, 2002 - 5:00 pm UTC

Tom kindly exlain about .obj , .o and pcode .. what are they

Tom Kyte
June 13, 2002 - 6:09 pm UTC

obj and o = object code. What C, and many other languages get compiled into. This is "machine code" -- the bits and bytes the OS will run.

pcode is like byte code (from java). It is a psuedo compiled code -- we interpret it and run it, instead of the OS

Inernal error

siva, June 14, 2002 - 1:12 am UTC

Hello TOM,
  While creating the ncomp i'm geting the following error. Is there any setting problems.

SQL>  alter session set plsql_compiler_flags = 'NATIVE';

Session altered.

SQL>  alter system set plsql_native_library_dir='/home';

System altered.

SQL> 
SQL>  create or replace   function factorial_native( p_n in number )
  2     return number
  3       is
  4       begin
  5           if ( p_n = 1 )
  6           then
  7               return 1;
  8           else
  9               return factorial_native( p_n-1 ) * p_n;
 10          end if;
 11      end;
 12   /

Warning: Function created with compilation errors.

SQL> sho err
Errors for FUNCTION FACTORIAL_NATIVE:

LINE/COL ERROR
-------- -----------------------------------------------------------------
0/0      PLS-00801: internal error [79704]
SQL> 


 one more doubt,
       Will it store any files in the operating system for this files.

Thanks and awaiting for your reply.

with regards,
siva 

Tom Kyte
June 14, 2002 - 7:21 am UTC

see
</code> http://docs.oracle.com/docs/cd/A91202_01/901_doc/appdev.901/a89856/12_tune.htm#48419 <code>

for the setup involved. There are one or two more init.ora type parameters you may need to set.

and -- you do have an ANSI C compiler installed right?

Internal error

siva, June 14, 2002 - 1:15 am UTC

Hello TOM,
I forgot to enter in the previous mail. I set this parameters too.

alter system set plsql_native_make_file_name =
'/opt/oracle/oraHome1/plsql/spnc_makefile.mk'
/
alter system set plsql_native_make_utility = 'make';

Thanks

with regards,
siva

Thanks, +

A reader, June 14, 2002 - 1:06 pm UTC

thanks for the clarification... I am trying to become aware of the latest features, so this really helped.

btw, reading your message a second time leaves me with
another question - you say 0x to 2x, when I think you
mean 1x (no time improvement) to 2x (calculations take
about half the time.) Perhaps its semantical, but its
relevant to ask if its possible to LOSE performance by
ncomping a routine?

thanks again, George

Tom Kyte
June 14, 2002 - 2:07 pm UTC

whoops -- I should have said 1x ... 2x

You will get somewhere between "no gain" and "2 times as fast" (or 1/2 as slow?)



What can I do under windows 2000 with MSVC 6.0

GuoHui Chen, June 15, 2002 - 7:37 pm UTC

Thanku Tom!
How to set the plsql_* parameters in initSID.ora

Tom Kyte
June 17, 2002 - 7:22 am UTC

For this -- I'll have to refer you to support. I don't have a windows environment to play around with on this one. I do know they didn't supply the makefile with 9.0.1 on windows for some reason. You'll need to check with support to see if it is available.

A reader, December 19, 2002 - 4:15 pm UTC

we compile it into p-code.
I'm sorry for this simple question. What is p_code?

Tom Kyte
December 19, 2002 - 6:31 pm UTC

like "psuedo" code.

like "byte" code.

an intermediate representation that lends itself to be interpreted quickly at runtime.

native compilation of sys/system packages

A reader, February 25, 2003 - 11:10 am UTC

Hi Tom,
This is on solaris 2.8/ oracle 9.2.0.1.
I read an article on OTN about native compilation of all oracle pl/sql packages such as standard, dbms*, etc. I created a new db instance with all plsql native compilation parameters set and sure enough it produced STANDARD__SYS__2.so etc objects in $ORACLE_HOME/plsql/userlibs directory and the instance seems to be OK. My questions:

1. would it help or hurt ncomp'ing all oracle packages?

2. i had to create a new db instance on this same machine. Again I set ncomp parameters. Oracle went ahead and re-compiled all the same objects under plsql/userlibs dir.. I think this is kind of redundant. I thought oracle would either name these objects specific to every instance ,or sense that natively compiled objects already exist and not overwrite them. can you please comment on this.

Tom Kyte
February 25, 2003 - 7:55 pm UTC

1) benchmark it, let us know what you find. You've got it all setup

2) how does oracle know that dbms_output is really the same dbms_output in both instances? to oracle -- it is just "code". each instance could have different pieces of code.

you should NOT use the same directory for both instances -- that could be fatal!

error after all required settings

June, April 16, 2003 - 4:34 pm UTC

after I set up system as following:

alter system set plsql_native_make_file_name = '/usr/local/oracle/product/9.2.0/plsql/spnc_makefile.mk' ;
alter system set plsql_native_make_utility = 'make';
alter system set plsql_native_library_dir='/usr/local/oracle/product/9.2.0/plsql/plsql_libs';
alter system set plsql_native_library_subdir_count = 1000;

and I verified with SA that we have the Sun Workshop 6 C Compiler installed. but still, I got following error after I submitted ' alter session set plsql_compiler_flags=native;' and tried to compile the procedure:

Errors for PROCEDURE POP_EMP_APRVD_RGSTN_TMP:

LINE/COL ERROR
--------
0/0 PLS-00801: internal error [79704]

what else did I miss here? any other profile setting on OS level?

thanks!

Tom Kyte
April 16, 2003 - 6:39 pm UTC

metalink.oracle.com says (after simply cutting and pasting the error message in)

Problem Description
-------------------

You want to use the native compilation option of Oracle9i.
You have set the plsql_compiler_flags to native.
You are trying to compile a pl/sql procedure from sql*plus.


You get the following error during compilation:

PLS-00801: internal error [79704]

You have checked that the relevant parameters are set

show parameter plsql%

NAME TYPE VALUE
-----------------------------------------------------------------
plsql_compiler_flags string NATIVE
plsql_native_c_compiler string /usr/local/bin/gcc
plsql_native_library_dir string /oracle/locallib
plsql_native_library_subdir_count integer 10000
plsql_native_linker string /usr/ccs/bin/ld
plsql_native_make_file_name string /oracle/plsql/spnc_makefile.mk
plsql_native_make_utility string /usr/local/bin/make
plsql_v2_compatibility boolean FALSE


Solution Description
--------------------

Check if the directories being referred while using NATIVE compilation are
present physically in the correct path. If not , create them manually before
attempting the compilation.


Explanation
-----------

The parameter plsql_native_library_dir decides the location of the native
libraries that are created during the pl/sql compilation.
If this directory is not physically present, then you might get this error.



error exists

June, April 21, 2003 - 2:07 pm UTC

Tom,

thanks for the information you provided. However after I changed the mode of directory to 777 for plsql_native_library_dir, and changed the plsql_native_c_compiler to the specific path where c compiler sits, I still get the error message. all the settings are as following:
NAME TYPE VALUE
------------------------------ ------- --------------
plsql_compiler_flags string INTERPRETED
plsql_native_c_compiler string /opt/SUNWspro/bin/cc
plsql_native_library_dir string /usr/local/oracle/product/9.2.0/plsql/plsql_libs
plsql_native_library_subdir_count integer 1000
plsql_native_linker string /usr/ccs/bin/ld
plsql_native_make_file_name string
/usr/local/oracle/product/9.2.0/plsql/spnc_makefile.mk
plsql_native_make_utility string make

and before recompiling, I did:
alter session set plsql_compiler_flags=native;

I have verified that the make file and native_linker is right in place. Is there any other trick to make it work?! thanks!

Tom Kyte
April 21, 2003 - 2:18 pm UTC

on the database server, do this:

ls -ld /usr
ls -ld /usr/local
ls -ld /usr/local/oracle
ls -ld /usr/local/oracle/product
ls -ld /usr/local/oracle/product/9.2.0
ls -ld /usr/local/oracle/product/9.2.0/plsql
ls -ld /usr/local/oracle/product/9.2.0/plsql/plsql_libs

lets see that output.

here is the output

June, April 21, 2003 - 4:56 pm UTC

here is the output for the requested info on the unix DB is on:

drwxr-xr-x 37 root sys 1024 Oct 15 2002 /usr
drwxr-xr-x 18 root root 512 Nov 1 12:52 /usr/local
drwxr-xr-x 23 oracle dba 2048 Apr 21 10:21 /usr/local/oracle
drwxr-xr-x 8 oracle dba 1024 Jun 21 2002 /usr/local/oracle/product
drwxr-xr-x 50 oracle dba 1024 Jan 15 11:11 /usr/local/oracle/product/9.2.0
drwxrwxr-x 9 oracle dba 1024 Apr 9 17:49 /usr/local/oracle/product/9.2.0/plsql
drwxrwxrwx 2 oracle dba 96 Apr 17 13:10 /usr/local/oracle/product/9.2.0/plsql/plsql_libs

the account I tried to compile pl/sql in native is non-dba account. As always, thank you for looking into it.


Tom Kyte
April 21, 2003 - 10:39 pm UTC

I'll have to refer you to support at this time. I cannot reproduce the issue and all "looks" ok from here.

native compilation ...

reader, February 21, 2004 - 12:27 pm UTC

Is it true that compiled coce of a pl/sql program unit is mapped into the PGA rather than in Shared pool (sga) in the case native compilation? If this is the case, if the session logs off that piece of compiled code is lost. How this helps in sharing? I am a little confused on this. Could you please help in clarifying this. Thanks.

Tom Kyte
February 21, 2004 - 1:38 pm UTC

native compilation creates binary object code (a dll in windows, a so, sl file in unixes and so on)

the OS manages code for us, on windows for example, windows shares the DLL code. On unix, the OS shares the text pages for shared objects like that.

the code isn't in the pga, data is in the pga (allocated variables and such) but the code itself is managed via the traditional OS mgmt routines and shared just like the single oracle binary is shared.

If it is interpreted ...

David, February 21, 2004 - 3:14 pm UTC

Tom, I read your explanation above for native compiled code that is managed by the OS. If that is the case, can I configure a smaller shared pool compared to interpreted codes? Is my understanding correct that interpreted pl/sql codes are placed in the shared pool now that memory space is saved in the shared pool if i used native compilation? Is this an advantage with regard to smaller shared pool? Thanks.

Tom Kyte
February 21, 2004 - 4:17 pm UTC

perhaps -- never really measured it. You'd have to natively compile everything.

There is still alot going on in the shared pool - even if all were natively compiled.

It would not be the motivation to use native compilation, it might be a small side effect.

can we set NATIVE compilation globally?

George, February 24, 2004 - 1:55 pm UTC

as always, thanks for your help.. this discussion has already been helpful.

Is it possible to set Native compilation on database startup?

Thanks, George



Tom Kyte
February 24, 2004 - 2:04 pm UTC

you can set it in the init.ora

No change in speed

Christo Kutrovsky, April 07, 2004 - 10:55 am UTC

Hi Tom,

I am testing native compilation with the exact same example you used. I had to increase the loop by 10 times because it was executing in 7 hsecs. 

Both native and interpreted execute in exactly 78 hsecs. No change. I know you said that you may get from same performance, up to 2 times performance, but still this is a case where native compilation should have made a difference.

Connected to:
Oracle9i Release 9.2.0.4.0 - Production
JServer Release 9.2.0.4.0 - Production

SQL> select object_name, object_type, param_value
  2  from dba_stored_settings where object_name like 'KUTRO%' and param_name = 'plsql_compiler_flags';

OBJECT_NAME                    OBJECT_TYPE
------------------------------ ------------
PARAM_VALUE
--------------------------------------------------------------------------------
KUTRO_INTER                    FUNCTION
INTERPRETED,NON_DEBUG

KUTRO_NATIVE                   FUNCTION
NATIVE,NON_DEBUG


SQL> set serverout on
SQL> alter session set plsql_compiler_flags = 'INTERPRETED';

Session altered.

SQL> declare
    l_start number;
    l_n     number;
begin
    l_start := dbms_utility.get_time;
    for i in 1 .. 10000
  2    3    4    5    6    7      loop
        l_n := kutro_native( 50 );
    end loop;
    dbms_output.put_line( (dbms_utility.get_time-l_start) ||
        ' hsecs...' || l_n );

  8    9   10   11   12   13      l_start := dbms_utility.get_time;
    for i in 1 .. 10000
    loop
        l_n := kutro_inter( 50 );
    end loop;
    dbms_output.put_line( (dbms_utility.get_time-l_start) ||
        ' hsecs...' || l_n );
 14   15   16   17   18   19   20  end;
/
 21  
77 hsecs...30414093201713378043612608166064768844300000000000000000000000000
80 hsecs...30414093201713378043612608166064768844300000000000000000000000000

PL/SQL procedure successfully completed.

SQL> SQL> /
78 hsecs...30414093201713378043612608166064768844300000000000000000000000000
79 hsecs...30414093201713378043612608166064768844300000000000000000000000000

PL/SQL procedure successfully completed.

SQL> /
73 hsecs...30414093201713378043612608166064768844300000000000000000000000000
73 hsecs...30414093201713378043612608166064768844300000000000000000000000000

PL/SQL procedure successfully completed.

SQL> 

Any comments?
 

Tom Kyte
April 08, 2004 - 9:02 am UTC

perhaps you have a sufficiently fast machine that for such a tiny bit of code it doesn't materially affect the run time (eg: most of the time is spent in the anonymous block for example, calling the functions).


tell you want, put the LOOP inside the functions and just call the functions once each (having them loop N times).


that'll time native vs interpreted more cleanly for you.

You got it !

Christo Kutrovsky, April 08, 2004 - 11:55 am UTC

Thanks Tom, 

I tried it, and now I can clearly see that the native one is much faster.

Here's the code I used:

alter session set plsql_compiler_flags = 'NATIVE';
create or replace function kutro_native(p_n in number,loop_times in number default null)
  return number
    is
    result number;
    begin
        if ( p_n = 1 )
        then
            return 1;
        else
          if loop_times is not null then
            for n in 1..loop_times loop
              result:=kutro_native( p_n-1) * p_n;
            end loop;
          else
            result:= kutro_native( p_n-1) * p_n;
          end if;
       end if;
       return result;
    end;
/


alter session set plsql_compiler_flags = 'INTERPRETED';
create or replace function kutro_inter(p_n in number,loop_times in number default null)
  return number
    is
    result number;
    begin
        if ( p_n = 1 )
        then
            return 1;
        else
          if loop_times is not null then
            for n in 1..loop_times loop
              result:=kutro_inter( p_n-1) * p_n;
            end loop;
          else
            result:= kutro_inter( p_n-1) * p_n;
          end if;
       end if;
       return result;
    end;
/
----------------------------------------
And the race:

set serverout on
alter session set plsql_compiler_flags = 'INTERPRETED';
declare
    l_start number;
    l_n     number;
begin
    l_start := dbms_utility.get_time;
    l_n := kutro_native( 50,10000 );
    dbms_output.put_line( (dbms_utility.get_time-l_start) ||
        ' hsecs...' || l_n );

    l_start := dbms_utility.get_time;
    l_n := kutro_inter( 50,10000 );
    dbms_output.put_line( (dbms_utility.get_time-l_start) ||
        ' hsecs...' || l_n );
end;
/

SQL> /
75 hsecs...30414093201713378043612608166064768844300000000000000000000000000
138 hsecs...30414093201713378043612608166064768844300000000000000000000000000

PL/SQL procedure successfully completed.

SQL> /
76 hsecs...30414093201713378043612608166064768844300000000000000000000000000
138 hsecs...30414093201713378043612608166064768844300000000000000000000000000

PL/SQL procedure successfully completed.

SQL> /
74 hsecs...30414093201713378043612608166064768844300000000000000000000000000
137 hsecs...30414093201713378043612608166064768844300000000000000000000000000


Just for reference this is Linux AS 2.1 with
cat /proc/cpuinfo
...
model name      : Intel(R) Xeon(TM) CPU 1.40GHz
stepping        : 1
cpu MHz         : 1397.212
cache size      : 256 KB
...

Thanks.
 

How to know the procedure was compiled

Thiru, July 01, 2004 - 9:40 am UTC

Hi Tom,

How do we determine in what mode a procedure/package/function was compiled? Whether NATIVE or INTERPRETED. We get errors trying to compile objects and then change the plsql_compiler_flags to INTERPRETED and then compiles.

Tom Kyte
July 01, 2004 - 11:23 am UTC

what errors -- and if you want interpreted (if that is what is working for you) why not just change it once and for all?

i would look in the directory on the server to see what so/sl files exists out there, they are named after the procedure/schema

Compiling to NATIVE

Jammi, October 17, 2004 - 10:31 am UTC

Being a very computational intensive application,I was looking to convert all the code to NATIVE from the present INTERPRETED. I read somewhere that to do so at the database level, change the parameter PLSQL_COMPILER_FLAGS and the other parameter required for NATIVE settings and then run utlirp.sql to invalidate and then validate with NATIVE compilation. Is this the right thing to do? Because when this script started running, it exited with errors like :
ERROR at line 1:
ORA-04045: errors during recompilation/revalidation of
SYS.CDC_DROP_CTABLE_BEFORE
ORA-04098: trigger 'SYS.CDC_ALTER_CTABLE_BEFORE' is invalid and failed re-validation

and when I tried to compile the trigger:

3/48 PLS-00905: object SYS.DBMS_CDC_PUBLISH is invalid

What is the right approach to convert my database to NATIVE.

Tom Kyte
October 17, 2004 - 10:56 am UTC

do a show errors on it, what errors does it have?

(note: you need not recompile everything 'native', you can just do your code... )

Here it is.

Jammi, October 17, 2004 - 11:00 am UTC

SQL> @utlirp
   SELECT obj# FROM trigger$ t WHERE
                    *
ERROR at line 2:
ORA-04045: errors during recompilation/revalidation of
SYS.CDC_CREATE_CTABLE_BEFORE
ORA-04098: trigger 'SYS.CDC_ALTER_CTABLE_BEFORE' is invalid and failed
re-validation



6 rows updated.


Commit complete.


System altered.


5 rows updated.


Commit complete.


System altered.


Package created.


Package body created.


Grant succeeded.


Package created.


Synonym created.


Grant succeeded.


PL/SQL procedure successfully completed.


System altered.


6 rows updated.


Commit complete.

DROP TABLE UTLIP_TEMP
*
ERROR at line 1:
ORA-04045: errors during recompilation/revalidation of
SYS.CDC_DROP_CTABLE_BEFORE
ORA-04098: trigger 'SYS.CDC_ALTER_CTABLE_BEFORE' is invalid and failed
re-validation

The script exited at this place. Thanks for the prompt response. 

Did not include this :

Jammi, October 17, 2004 - 11:02 am UTC

SQL> alter trigger SYS.CDC_ALTER_CTABLE_BEFORE compile;

Warning: Trigger altered with compilation errors.

SQL> sho err
Errors for TRIGGER SYS.CDC_ALTER_CTABLE_BEFORE:

LINE/COL ERROR
-------- -----------------------------------------------------------------
3/7      PL/SQL: Statement ignored
3/48     PLS-00905: object SYS.DBMS_CDC_PUBLISH is invalid 

Tom Kyte
October 17, 2004 - 11:34 am UTC

and if you look at the trigger body, what do you see there -- anything obvious (you have an invalid trigger in your database, can you figure out why? that is what I'm trying to lead you towards here -- peek at the trigger, so, can you tell WHY it is invalid.

I'm praying you are doing this on your test box, please say you are...)

Jammi, October 17, 2004 - 4:08 pm UTC

I am not getting  anywhere. The trigger calls the package and the package looks at the trigger.

Compiling triggers gives error pointing to the package SYS.DBMS_CDC_PUBLISH 
SQL> alter trigger SYS.CDC_ALTER_CTABLE_BEFORE compile;

Warning: Trigger altered with compilation errors.

SQL> sho err
Errors for TRIGGER SYS.CDC_ALTER_CTABLE_BEFORE:

LINE/COL ERROR
-------- --------------------------------------------------------------
3/7      PL/SQL: Statement ignored
3/48     PLS-00905: object SYS.DBMS_CDC_PUBLISH is invalid

When compiling the package gives the error:


SQL> ALTER PACKAGE DBMS_CDC_PUBLISH COMPILE;
ALTER PACKAGE DBMS_CDC_PUBLISH COMPILE
*
ERROR at line 1:
ORA-04098: trigger 'SYS.CDC_ALTER_CTABLE_BEFORE' is invalid and failed re-validation.

Yes Tom, its a Test box thankfully.



 

Tom Kyte
October 17, 2004 - 5:11 pm UTC

disable the trigger, then compile, then re-enable the trigger.

Jammi, October 20, 2004 - 11:04 am UTC

I am in the process of creating db on interpreted and then having one schema under native mode.
If I have an export dump that was generated with INTERPRETED, how do I go about importing with NATIVE.
If I import first and then recompile all objects of that schema, will all objects get compiled with NATIVE. Will there be any issues with TYPE objects.

Tom Kyte
October 20, 2004 - 11:46 am UTC

just import and rebuild anything you want natively compiled -- anything you want (types with code, packages whatever)

Jammi, October 20, 2004 - 12:06 pm UTC

The db is on INTERPRETED mode. I did the following:
create or replace procedure p3
as
begin
dbms_lock.sleep(1);
end;
/
Procedure created.
create type t2 as object(a number);
/
create table t2_tbl of t2;

alter session set plsql_compiler_flags='NATIVE';

alter procedure p3 compile;
Procedure altered.

alter type t2 compile;

ORA-02311: cannot alter with COMPILE option a valid type with type or table dependents

So this is where the issue is.

select * from user_stored_settings where object_name in ('P3','T2') and param_name like 'plsql%';

T2 29051 TYPE plsql_compiler_flags INTERPRETED,NON_DEBUG

P3 29049 PROCEDURE plsql_compiler_flags NATIVE,NON_DEBUG

Tom Kyte
October 20, 2004 - 12:15 pm UTC


but -- your type contains no code, so no big deal....

Jammi., October 20, 2004 - 12:37 pm UTC

What you meant by code, is it TYPE BODY? I did add a body to the TYPE and without any table created of that TYPE, the compilation is effective. All our TYPE objects do have tables created of it. So the schema would have both INTEPRETED and NATIVE objects. Is there a way to get to a uniform compiler flag for the whole schema?

Thanks for your time Tom.

Tom Kyte
October 20, 2004 - 4:37 pm UTC

you would set it at the system level before importing.

Jammi, October 20, 2004 - 5:02 pm UTC

I could get the db to be on Native mode. There were issues with compiler and the plsql_native_library_subdir_count=1000. Changing this to 0 made the difference with the compiler change.

So with this db on NATIVE, if I import an INTERPRETED dump, will all the objects get compiled as NATIVE by default or do we have to compile them after import? Also as per your guideline, the TYPEs should be NATIVE after import with sytem level flag as NATIVE.

Just clarifying the point. Thanks again.

Tom Kyte
October 20, 2004 - 5:17 pm UTC

never tried - when you give it a try, follow up and let us know...

Jammi, October 20, 2004 - 5:56 pm UTC

I did the import(INTERPRETED) on a NATIVE db. The object got created with INTERPRETED mode. And as I had mentioned before, when there are table dependencies, the TYPE objects compilation does not go through. While all other objects (procedures,functions etc..) gets compiled in NATIVE mode withou any problem. So what I am doing is:

a. import first without rows.
b. drop the tables of TYPE objects( after creating a create table script of the TYPE objects).
c. compile the TYPE and TYPE body and all other objects as NATIVE.
d. create back those tables.
e. import the data.

Hopefully, I expect this to work. Shall keep the results posted. Meanwhile, your opinion on the above steps ?



Tom Kyte
October 20, 2004 - 9:01 pm UTC

seems like alot of work unless you've already proven that doing this makes you "2 times faster".

Jammi, October 21, 2004 - 10:27 am UTC

Yes. It's a task. But when I try to import the data only, there is a conflict of Object Identifer as the table was created locally after dropping and natively compiling the TYPE. I have read in one of your threads about going through this issue, but am unable to find it. Any suggestions at this point?

Thanks


Tom Kyte
October 21, 2004 - 2:47 pm UTC

nope, i've never been down this particular path. (frankly, i don't think it will be worth it for the type bodies -- if you have a ton of code in them, modularize it and move it into packages and have the type bodies be mostly calls to packages)

Compare Pro*C code with Native Compiled PL/SQL code on performance and size

Tony, October 27, 2004 - 2:27 am UTC

Tom,

1. Can you compare Pro*C Code with Native Compiled PL/SQL code on performance? I've calculation intensive Pro*C code and have the same logic implemented in native compiled PL/SQL. Which one will be faster?

2. Can you compare the size of interpreted PL/SQL code with native compiled PL/SQL code?

3. Can I say that native compilation has obviated or eliminated the need of Pro*C? If no, Why?


4. Where are native compiled codes (.obj, .o etc) stored? Are they in Database or OS?

5. How to find if a procedure is native compiled? Is there any system table for the purpose?

6. Source code of a procedure is stored/viewed in/from USER_SOURCE. Where is p-code stored in the database? How to find it?

7. Will I have to re-compile native compiled procedures when the database is up-graded, for example from 9i to 10g?

Thanks in advance.


Tom Kyte
October 27, 2004 - 7:40 am UTC

1) depends.  do I have to pull a million rows out of the database, over the network to my pro*c application running on another machine-- compute something -- and then put it back?  

maybe plsql interpreted would beat it just because of the network.
maybe not.

this is an unanswerable question, you would "benchmark" a prototype implementation.


2) no, one is pcode stored in database tables, interpreted by a Virtual machine.  the other is object code, stored in OS files (or blobs in 10g) and run by the OS.  apples and toaster ovens

3) no.  ncomped code is generally (mostly, not always) faster than interpreted by a small margin.  I can write some nasty bad pro*c code that outperforms plsql by many orders of magnitude (most recent case was to cartesian product a table with itself and compute the distance between two strings for a name match.  it would have taken years in sql, weeks in plsql, we did it overnight in pro*c running in parallel).

there will probably never be "a language", "a universal solution" for all problems.

4) os in 9i, either or in 10g

5) 
ops$tkyte@ORA9IR2.US.ORACLE.COM> alter session set plsql_compiler_flags = 'INTERPRETED';
 
Session altered.
 
ops$tkyte@ORA9IR2.US.ORACLE.COM>
ops$tkyte@ORA9IR2.US.ORACLE.COM> create or replace
  2  function factorial_interpreted( p_n in number ) return number
  3  is
  4  begin
  5          if ( p_n = 1 )
  6          then
  7                  return 1;
  8          else
  9                  return factorial_interpreted( p_n-1 ) * p_n;
 10          end if;
 11  end;
 12  /
 
Function created.
 
 
ops$tkyte@ORA9IR2.US.ORACLE.COM>
ops$tkyte@ORA9IR2.US.ORACLE.COM>
ops$tkyte@ORA9IR2.US.ORACLE.COM> alter session set plsql_compiler_flags = 'NATIVE';
 
Session altered.
 
ops$tkyte@ORA9IR2.US.ORACLE.COM>
ops$tkyte@ORA9IR2.US.ORACLE.COM> create or replace
  2  function factorial_native( p_n in number ) return number
  3  is
  4  begin
  5          if ( p_n = 1 )
  6          then
  7                  return 1;
  8          else
  9                  return factorial_native( p_n-1 ) * p_n;
 10          end if;
 11  end;
 12  /
 
Function created.
 
ops$tkyte@ORA9IR2.US.ORACLE.COM>
ops$tkyte@ORA9IR2.US.ORACLE.COM> set echo off
Enter to continue
 
=================================================================
 
and the race is on...
 
 
ops$tkyte@ORA9IR2.US.ORACLE.COM>
ops$tkyte@ORA9IR2.US.ORACLE.COM>
ops$tkyte@ORA9IR2.US.ORACLE.COM> alter session set plsql_compiler_flags = 'INTERPRETED';
 
Session altered.
 
ops$tkyte@ORA9IR2.US.ORACLE.COM>
ops$tkyte@ORA9IR2.US.ORACLE.COM> declare
  2          l_start number;
  3          l_n     number;
  4          l_e1    number;
  5          l_e2    number;
  6  begin
  7          l_start := dbms_utility.get_time;
  8          for i in 1 .. 5000
  9          loop
 10                  l_n := factorial_interpreted( 50 );
 11          end loop;
 12          l_e1 := dbms_utility.get_time-l_start;
 13          dbms_output.put_line( l_e1 || ' hsecs...' || l_n );
 14
 15          l_start := dbms_utility.get_time;
 16          for i in 1 .. 5000
 17          loop
 18                  l_n := factorial_native( 50 );
 19          end loop;
 20          l_e2 := dbms_utility.get_time-l_start;
 21          dbms_output.put_line( l_e2 || ' hsecs...' || l_n );
 22
 23          dbms_output.put_line( l_e2 || ' is ' || round(l_e2/l_e1*100,0) || '% of ' || l_e1 );
 24  end;
 25  /
30 hsecs...30414093201713378043612608166064768844300000000000000000000000000
17 hsecs...30414093201713378043612608166064768844300000000000000000000000000
17 is 57% of 30
 
PL/SQL procedure successfully completed.
 
ops$tkyte@ORA9IR2.US.ORACLE.COM>
ops$tkyte@ORA9IR2.US.ORACLE.COM> set echo off
OBJECT_NAME                   : FACTORIAL_INTERPRETED
OBJECT_ID                     : 32227
OBJECT_TYPE                   : FUNCTION
PARAM_NAME                    : plsql_compiler_flags<b>
PARAM_VALUE                   : INTERPRETED,NON_DEBUG</b>
-----------------
OBJECT_NAME                   : FACTORIAL_NATIVE
OBJECT_ID                     : 32228
OBJECT_TYPE                   : FUNCTION
PARAM_NAME                    : plsql_compiler_flags<b>
PARAM_VALUE                   : NATIVE,NON_DEBUG</b>
-----------------
 
PL/SQL procedure successfully completed.


6) in idl$ tables in the sys schema, not very interesting really.

7) invalidation and recompilation generally happens as part of an upgrade yes. 

Native Compilation of Unanimous PL/SQL Block

Tony, October 28, 2004 - 12:46 am UTC

Tom,

Is it possible to native compile unanimous PL/SQL blocks?



Tom Kyte
October 28, 2004 - 7:44 am UTC

anonymous blocks....

named blocks (procedures, packages, functions) are ncomp'able. not anonymous blocks (which should be teeny tiny and not containing anything computationally expensive anyhow)

Compiler for Native Compilation in Windows/Unix

Tony, October 28, 2004 - 2:33 am UTC

Tom,

Can we use any C compiler ( Turbo, Borland C etc ) for Native Compilation in Windows or UNIX?

Thanks in advance.

Tom Kyte
October 28, 2004 - 7:50 am UTC

no, only the supported system compilers (generally one per platform) are supported. support can clarify what is supported on your platform.

good

sudanand, November 26, 2004 - 5:07 am UTC

This is good web site that i got more important information about pl/sql progrmming. I hope that this web site will help me in future. And I would like to give most expensive thanks to the web site. I hope that I will get more important help from this web site. Thanks

sudanand2001@yahoo.com

native compilation

Dave, January 10, 2005 - 5:50 pm UTC

<quote>obj and o = object code. What C, and many other languages get compiled into. This is "machine code" -- the bits and bytes the OS will run.<quote>

When one accesses a pl/sql procedure compiled "native", where OS will load the C code to run it? Which memory? pga or ? It has to load it to some memory before it executes? Thanks.


Tom Kyte
January 10, 2005 - 6:13 pm UTC

it loads into shared text area's generally -- most OS's share text. So, neither PGA, SGA -- just OS memory.

how much memory?

reader, January 10, 2005 - 7:20 pm UTC

If it is using os memory, how do I know how much memory I should have to process, if I am using "native"? Is there a way to setimate? Thanks.

Tom Kyte
January 10, 2005 - 7:27 pm UTC

it is just "os text", suppose you could use nm on it in unix to see sizes -- but I've never seen anyone do that, it would be micromanaging it a bit more than i think we have to.

Cons of native PL/SQL in 10g

Edgar, January 11, 2005 - 8:42 am UTC


There are many articles on *.oracle.com describing advantages of 10g native PL/SQL compilation.
Wow.
Seems, in every new 10g database i'm going to create, all PL/SQL including SYS schema, should be nativelly compiled (just by setting init.ora parameters PLSQL_CODE_TYPE=NATIVE, PLSQL_NATIVE_LIBRARY_DIR before database creation)...

BUT,
Why default value for PLSQL_CODE_TYPE still is INTERPRETTED..?

Let assume, my application use a lot of stored PL/SQL units, but algorithms are not "computationally-or-loop-intensive". Even let assume, my application does not use PL/SQL at all.

In that case, what potential problems/limitations, what DISADVANTAGES have native PL/SQL compared to interpretted?


Tom Kyte
January 11, 2005 - 10:46 am UTC

I've never measured it -- for the simple reason that 10g is running my interpreted code much much faster than 9i ever did and it was faster than fast enough back them, now, it just is fast.

I'm just using interpreted code.




Programmer

Raju, January 12, 2005 - 12:40 am UTC

Tom, u r simply amazing..!!!
u r born with ultimate brains...!!!
u make things look simple and easy to understand, u r my Guru..!!

Tom Kyte
January 12, 2005 - 8:22 am UTC

but my brains still have a horribly hard time reading stuff like this.

"u"
"r"

those are not words. They are characters!


(pet peeve of mine, maybe in an instant messenger session, but in written correspondence, never)

10g interpretted versus native

Edgar, January 12, 2005 - 4:20 am UTC

So, i'm going to use interpretted mode after migration to 10g, like You did.
Some cons of native are clear for me:
1.) cost of C compiler licenses for our platform
2.) additional considerations needed regarding backup/recovery, failover, OS and Oracle upgrades/patching

Theorethically, interpretted virtual machine code (PL/SQL and Java for example) offer more robustness.

Thank You,
Sincerely



ncomp on IBM z/OS 1.5

TyĂĽtyĂĽ, January 25, 2005 - 5:25 am UTC

Hello Tom!

We are using 9.2.0.5.21 on IBM z/OS 1.5.
The release notes said that native compilation is not supported on this platform.

It would be a great help to know whether this means that it will not be supported on this platform in the future or simply it is not ready yet but Oracle is working on.

We are facing some heavy calculations (with no SQL) and the performance is just on the acceptable level. I think it would be a possible improvement point to ncomp our packages.

Thank you!

Tom Kyte
January 25, 2005 - 9:24 am UTC

metalink.oracle.com would be the best place for that sort of a question.


10g would give you more speedup in compute intensive code than ncomp would...

(1)can we see the P-code ? (2)Confusion regarding CURSOR..

Debashis Payin, February 16, 2005 - 5:56 am UTC

Hi Tom

Good morning. I have a query . Is there any TABLE or VIEW from
which we can see the p-code that has been generated for a subprogram ?
I mean , can we access the p-code (as compared to Source Code from
ALL_SOURCE etc) for a subprogram ?

Another point I'd like to bring into your consideration .I am
having one confusion for a long time . It's regarding CURSOR in ORACLE .
What actually happens in Oracle , when we declare and open a
CURSOR ? In many books ,articles and websites , i have seen that
Oracle doesn't copy the data anywhere in the MEMORY . But in some
books/articles , they are saying that when we declare/open a CURSOR ,
it's just a pointer to the table and it stores the data in a virtual
table and it's called CONTEXT AREA . If it's true , then where in the
Virtual Table resides ? What actually is that CONTEXT AREA ? And if
it's true , then ORACLE might store
the data(let's assume in the case
of a ONE-MILLION-ROW table !!!!) into that VIRTUAL TABLE.... !!!!
I think it's not logical to think that way . But , if it doesn't store the data , then ONE-MILLION times I/O contention(with datafile) must be there !!!! Here comes the confusion .
I am posting a Stored Procedure over here . Hope you have EMP table(in Oracle database) to run this procedure .What I wanted to show is
(1) I am declaring a cursor
(2) Then I am deleting the table data as well as doing a commit . That
means there is no data in the emp table .
(3) Now , when i am fetching the data through CURSOR(after deleting
the table data !!!!! ), I am still being able to get that data .

Probably the reason for this is that when I am deleting the Table data , it's going to the Rollback Segement . And this Stored Procedure is being able to retrieve the data from the Rollback Segment . But if I use TRUNCATE instead of DELETE-n-COMMIT , this Stored Procedure will produce "ORA-08103: object no longer exists" error in the output.

/************** start of SP ***************************************************/

Procedure TEST_CURSOR( P_EMPNO IN NUMBER )
IS
-- Purpose: To see where in the memory structure
-- Oracle stores data when a Cursor is declared/opened .
-- Person : Debashis Payin Date : Monday, 14 February 2005
CURSOR C_EMP IS
SELECT ENAME
FROM EMP
WHERE EMPNO = P_EMPNO ;
R_EMP C_EMP%ROWTYPE ;

BEGIN
OPEN C_EMP ;
DELETE FROM EMP; /* delete the table data */
COMMIT; /* do a COMMIT also !!!! */
LOOP
FETCH C_EMP INTO R_EMP;
EXIT WHEN C_EMP%NOTFOUND ;
DBMS_OUTPUT.PUT_LINE('The employee is : ' || R_EMP.ENAME );
END LOOP ;

CLOSE C_EMP;

EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('Error ' || SQLERRM);
END; -- Procedure TEST_CURSOR

/************** end of SP ***************************************************/


Plz note : There is nothing wrong in this procedure . I don't want any rectification to this Stored Procedure .
What i want is to know the behavior of CURSOR .



Thanks
Debahis Payin
xnutron@yahoo.co.in


Tom Kyte
February 16, 2005 - 8:21 am UTC

it is in the idl tables in the dictionary but it is just raw BYTES of data, nothing you can or would want to look at.


think of a sql query like a program. we execute the program, reading data as needed. If you had a program to open a file and process the rows row by row -- would you "copy the data somewhere first and then process it?" no, you would open the file, read a line, process it, read a line, process it and so on. You would have a "file pointer" that is remembering where in the file you are. We do the same.

On the other hand, if you had to report out "counts by job" from a file full of employee information -- you might set up an array "job" and "cnt" and start reading row by row and adding jobs to the array when they don't exist and counting records that match. If the array got really really big, you might put some of it to a temporary file on disk to avoid exhausting all memory. We do the same.




Thanks Tom.. but

Debashis Payin, February 22, 2005 - 1:43 am UTC

Hi Tom

Good morning . Thanks for your reply . Got the confusion cleared . But still having a query . Your answer implies that , when we open a CURSOR ( be it a OPEN statement or a CURSOR FOR LOOP )Oracle generally doesn't copy the data somewhere else . But if the query involves some sorting/calculation operation on that data , Oracle might decide to store the data into some temporaray table . Ok .. now could you please tell me that where in the temporay data get stored ?

Thanks in advance

Debashis Payin
Bangalore

Tom Kyte
February 22, 2005 - 8:35 am UTC

in temp?

plsql native compiler in 10g

vijaya, March 01, 2005 - 1:51 pm UTC

I am getting error while compiling plsql in native mode.

1  create or replace
 2    function factorial_native( p_n in number ) return number
 3      is
 4    begin
 5        if ( p_n = 1 )
 6       then
 7           return 1;
 8       else
 9           return factorial_native( p_n-1 ) * p_n;
10       end if;
11*  end;
12  /

arning: Function created with compilation errors.

QL> show error
rrors for FUNCTION FACTORIAL_NATIVE:

INE/COL ERROR
------- -----------------------------------------------------------------
/10     PLS-00925: native compilation failed: Unable to create C file
        (c:\ORACLE\PRODUCT\10.1.0\ORADATA\TORONTO\natlib\d156\
        FACTORIAL_NATIVE__SYS__F__53715.c)


SQL> show parameter plsql

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
plsql_code_type                      string      NATIVE
plsql_compiler_flags                 string      NATIVE, NON_DEBUG
plsql_debug                          boolean     FALSE
plsql_native_library_dir             string      c:\ORACLE\PRODUCT\10.1.0\ORADA
                                                 TA\TORONTO\natlib
plsql_native_library_subdir_count    integer     1000
plsql_optimize_level                 integer     2
plsql_v2_compatibility               boolean     FALSE
plsql_warnings                       string      ENABLE:ALL
SQL>
 

Tom Kyte
March 01, 2005 - 2:10 pm UTC

does that directory exist on the database server and is it writable by Oracle itself (the low privileged account that the database service runs as)

plsql native execution in 10g

vijaya, March 01, 2005 - 2:30 pm UTC

Yes the folder natlib is there in c:\ORACLE\PRODUCT\10.1.0\ORADATA\TORONTO\natlib.
However d156 directory is not created.
As per the 10g plsql user's guide, spnc_commands file is in c:\oracle\product\10.1.0\db_2\plsql directory.
I have xp home and amd athlon xp 3000 processor. I have also visual 6.0 c++ installed on the pc. IS there any specific configuration required in spnc_command file. How is d156 directory created?

Tom Kyte
March 01, 2005 - 3:29 pm UTC

</code> http://docs.oracle.com/docs/cd/B10501_01/appdev.920/a96624/12_tune.htm#48417 <code>

you create it, see that link.

or you set the subdir count to 0

views and triggers based on native functions ... how would that work?

John Hurley, May 17, 2005 - 5:26 pm UTC

Sometimes as a DBA you inherit things. If we have an application that uses a bunch of views that have functions in them (mostly converting back and forth from oracle date fields into 6 and 8 digit character fields ... sigh) there are some cpu consumption issues.

Is it possible to think about re-compiling the functions into native?

What's the impact on a view that uses those functions? Can you recompile a view native?

There are some triggers also that use the functions and I am assuming that can recompile those?

Any roadblocks or things I am not thinking about correctly?

Thanks in advance


Tom Kyte
May 17, 2005 - 6:32 pm UTC

you can compile the plsql only but unless the plsql is computing an eigen vector or something, you won't see much from this -- if they are simple little things

I'd be more inclined to look at the functions called from the view and see if I couldn't

a) just use SQL (case is very powerful, decode, etc)
b) use a SCALAR subquery if the function did a little lookup or something

that would give biggest bang for the buck.

And use scalar subqueries to call the function, instead of:


where x = F();

use

where x = (select f() from dual)

you might be surprised what can happen in case 1 vs case 2 as far as number of calls go

A reader, May 18, 2005 - 9:05 am UTC

<quote>
And use scalar subqueries to call the function, instead of:
where x = F();
use
where x = (select f() from dual)
</quote>

Can you please explain why. It seems to me that it runs slower and makes more latches. Or am I missing a point?
Thanks


Tom Kyte
May 18, 2005 - 9:23 am UTC

ops$tkyte@ORA9IR2> create or replace function f return varchar2
  2  as
  3  begin
  4          dbms_application_info.set_client_info( userenv('client_info')+1 );
  5          /* assume we do something here that takes 0.01 seconds */
  6          return 'Hello World';
  7  end;
  8  /
 
Function created.
 
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> exec dbms_application_info.set_client_info(0);
 
PL/SQL procedure successfully completed.
 
ops$tkyte@ORA9IR2> select * from scott.emp where ename = f();
 
no rows selected
 
ops$tkyte@ORA9IR2> select userenv('client_info') from dual;
 
USERENV('CLIENT_INFO')
----------------------------------------------------------------
14
 
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> exec dbms_application_info.set_client_info(0);
 
PL/SQL procedure successfully completed.
 
ops$tkyte@ORA9IR2> select * from scott.emp where ename = (select f() from dual);
 
no rows selected
 
ops$tkyte@ORA9IR2> select userenv('client_info') from dual;
 
USERENV('CLIENT_INFO')
----------------------------------------------------------------
1
 


If the function ends up getting called once per row, that could be "bad" (context switch back and forth and back and forth).

Even if the function takes inputs:

ops$tkyte@ORA9IR2> create or replace function f(p_job in varchar2) return varchar2
  2  as
  3  begin
  4          dbms_application_info.set_client_info( userenv('client_info')+1 );
  5          /* assume we do something here that takes 0.01 seconds */
  6          return lower(p_job);
  7  end;
  8  /
 
Function created.
 
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> exec dbms_application_info.set_client_info(0);
 
PL/SQL procedure successfully completed.
 
ops$tkyte@ORA9IR2> select * from scott.emp where ename = f(job);
 
no rows selected
 
ops$tkyte@ORA9IR2> select userenv('client_info') from dual;
 
USERENV('CLIENT_INFO')
----------------------------------------------------------------
14
 
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> exec dbms_application_info.set_client_info(0);
 
PL/SQL procedure successfully completed.
 
ops$tkyte@ORA9IR2> select * from scott.emp where ename = (select f(job) from dual);
 
no rows selected
 
ops$tkyte@ORA9IR2> select userenv('client_info') from dual;
 
USERENV('CLIENT_INFO')
----------------------------------------------------------------
5


The scalar subquery caching that kicks in can be very beneficial in reducing the number of invocations.

 

What about the built-in Pl/SQL, should I change to NATIVE too ??

Alfredo Diaz, June 29, 2005 - 5:27 pm UTC

Hi Tom.
We are thinking to change to native compilation one of our Database (9.2.0.4) from interpreted.
I read some not official information and also some bulletin in Metalink. But (maybe because a language issue) I still have a dude about change our own development (our PL/SQL) and the built-in ones (that ones that come with Oracle the first time you install a new database).
Most of the advices I found in the net talk abut change EVERYTHING or NOTHING. That means that we should re-compile our all development and also all those PL/SQL that comes with Oracle from the "manufactury".
Four us, this is a key information to take the right decision.

Thank you for advance, Alfredo Diaz.

Tom Kyte
June 29, 2005 - 8:22 pm UTC

in radically extreme cases -- a procedure might run 2x as fast (computing a factorial for example)

but in most cases, you are not going to see that.

are you sure you even want to go down this path? What sort of payback are you expecting? (I just find it makes you different enough from everyone else that is just seems to be not worth the extra effort)

heck, you want your plsql to go faster? just upgrade to 10g.

Wrong answer in the last followup ??

Alfredo Diaz, June 30, 2005 - 11:48 am UTC

I don´t think the answer in the last followup was the right one.
Anyway, if somebody else have the same dude, I got some new from Metalink Guys :

From: Oracle, Asim chowdhury 30-Jun-05 06:42
Subject: Re : What about the built-in Pl/SQL, should I change to NATIVE too ??

Correct,you need to compile the built in package also.
Please refer the note 151224.1
Also please go through the following site
</code> http://otn.oracle.com/tech/pl_sql/htdocs/ncomp_faq.html#c_compiler <code>

Regards
Asim

Tom Kyte
June 30, 2005 - 12:02 pm UTC

you can benchmark and prove me wrong, no worries from my end on that.


"show me"

native compilation and context switching

A reader, May 02, 2006 - 4:34 pm UTC

Tom,
I understand that natively compiled code is (should be) faster than p-code. Let's say we natively compiled custom function and use it in SQL query. What about context switch in this case? Is there any? If this is natevily compiled code, it should be just called without any context switching - or not? What is exactly context switching if there is no PLSQL code (p-code) and only linked object code?
Thanks a lot!

Tom Kyte
May 03, 2006 - 1:35 am UTC

it could be even worse :)

you are going from a sql context to a plsql vm context to binary code and back.

context switching is the act of going from environment 1 (sql) to environment 2 (plsql) - you are not "avoiding" it at all - you are still going from sql to plsql.

native compilation and context switching

A reader, May 03, 2006 - 9:22 am UTC

So - plsql context is not avoidable? There is technically no way of building functions similar to Oracle internal functions (like ln or sin for example)? Would be very nice to have!!!

Tom Kyte
May 03, 2006 - 12:53 pm UTC

... There is technically no way of building
functions similar to Oracle internal functions ...

absolutely there is - however, there will be a context switch. Each release makes this less expensive, but it is *still* there and will likely always be.

native compilation and context switching

A reader, May 03, 2006 - 1:02 pm UTC

Sorry - I'm confused. Are you saying there is also a context switch when you have select ln(column) from some_table? Or there is not? If there is - in this case ANY function call results in context switch and why using Oracle embedded functions is better then user ones? If there is not - back to the original question: is it possible to build user function that is acting in exactly the same way as native Oracle?

Tom Kyte
May 03, 2006 - 1:32 pm UTC

you said:

"building functions similar"

that is the ORIGINAL question. So, you have a new original question, different from the old original question.

"is it possible to build user function that is acting in exactly the
same way as native Oracle?"

Yes: it will ACT exactly the same as an Oracle builtin function - you cannot tell the difference.

However: it will NOT be part of the sql language, it will be an external language and comes with the associated baggage.

You just don't like to answer "NO" when it relates to Oracle

A reader, May 03, 2006 - 1:37 pm UTC

I think you perfectly understood the original question as well, but you just don't like to answer "NO" on any question like "is it possible to do {something} in Oracle" :-)

Tom Kyte
May 03, 2006 - 2:40 pm UTC

No, I just read what is here. Honest.

You asked (literally)

"There is technically no way of building
functions similar to Oracle internal functions"

the only answer to that is "Yes, there is - it is called Plsql"


Then you asked (literally)

"is it possible to build user function that is acting in exactly the
same way as native Oracle? "

the only answer to that is "yes, there is"


Now, if you ask "can I write my own LN() function that performs just like the builtin LN() function - eg: link my own code directly into the Oracle kernel and have it be as if I wrote part of the kernel itself" the answer would be:

NO - that would neither be safe, nor permitted.

Resource consumption

Daniel, October 15, 2006 - 1:56 pm UTC

Hi Tom,
Could you please share your experience with me on the following questions:

I have a procedure which is the heart of the banking application i,e, user/application calls come from tuxedo onto the database server, where every call first executes a main Function say ProcessCust(); This is a plsql function. This function then interpets the call (which is basically having a message in iso format). The function breaks the input message which is vrchar2 and parse it. Like the first 3 characters store the action required(like opening a new customer, updating its balance, etc etc), then rest of the string contains the actual body (like if its new customer, then the text would contain fname,lname, address etc etc).
In short the function ProcessCust() parses the message(and i found lots lots if if then plsql clauses inside) and lots of substring, ltrim etc. The function then make calls to corresponding procedures like createcustomer() etc which are also plsql stored procs defined in the same database.

Now from the statspack i see that 90% of the cpu time used (under the first section of statspack) point to this function ProcessCust(). Ironically there is no other info that guides me what actually took so much cpu from this fucntion(i mean the fucntion has some bit of sql calls too, but those sqls do not appear in the subsequent section, which can only mean that the function is having lots if if then , sunstr etc, which are basically using that much cpu and statspack basically does not go into details).

Anyway, what i would like to do is to recompile that function into native. I do not want the whole db to be native compiled. So I reckon its possible to just compile that function alone into native mode. Questions:
1. With the kind of example you provided in this thread, i could have a test case(stress load which calls this function many times for all events) where i can find the elapsed time taken. I can run this for both inter and compiled. If i see significant time reduction, i will go for native. However I also would like to measure other factors.
How can i include a code in the same test that tells me How much CPU was used in first interpreted and then compiled case??is there an easy way to do that like calling an oracle function before and after the for loop test you showed, that will also give me cpu secs used????

2. Do you think cpu time will reduce in native calls? it should right??in your test, was it the case? or you think more cpu is required? i reckon .obj code should use lot less cpu than plsql interpet calls?

3. Does native plsql compilation increase the memory usage of the machine ??

4. We are on 9i rel 2, is there any major siginificant improvements in plsql native mechanism between 9i and 10g?

5, We will migrate to 10g in 6 months time, is there a document that yo can refer that 10g plsql is that much faster than 9i??

6. If all fails, how does one fine tune a case which i explained where statspack shows a function using almost 80-90 of the cpu time for the duration and no sqls are shown?is there an ydetailed level of statspack??

Regards
Daniel




Tom Kyte
October 16, 2006 - 7:33 am UTC

the cpu time reported by statspack is a summation OF ALL of the cpu used by everything invoked by this procedure.

It is not saying "you did 90% in this funtion", but rather, when you run this function - everything it does and everything it calls does and every sql it runs does this much"

<quote>
--
-- SQL statements ordered by CPU

ttitle lef 'SQL ordered by CPU '-
'DB/Inst: ' db_name '/' inst_name ' '-
'Snaps: ' format 99999999 begin_snap '-' format 99999999 end_snap -
skip 1 -
'-> Resources reported for PL/SQL code includes the ' -
'resources used by all SQL' -
</quote>


so, doubt you are looking at the "right place". If you want to figure out where your time is spent in detail in plsql, you must look at using dbms_profiler.



cpu consuming sql from statspack

daniel, October 18, 2006 - 11:26 am UTC

Hi Tom,
What I see in the top 5 timed events of my statspack is the:
Event Waits Time (s) Ela Time
-------------------------------------------- ------------ ----------- --------
CPU time 19,757 44.62

Then when I looked at the section for sqls orderded by buffer gets i see:
CPU Elapsd
Buffer Gets Executions Gets per Exec %Total Time (s) Time (s) Hash Value
7,616,928 95,061 80.1 11.5 11212.33 12510.73 3919012089
Module: fts_request@mware02 (TNS V1-V3)
begin :output_fields := precamm ( :input_fields ) ; END ;

So I reckon 11212 secs out of 1957 means this sql is the most cosuming cpu time. Now the problem is this is a function called precamm in my database which is composed of lots of if then else plus sqls. But I dont see any sqls further in statspack taking up cpu time.
So I thought of compiling this into native,

I wish i can paste here full statspack and that function(am sure programmer must have put something very bad as a code).
But i tried but there is not enough space in the reply box here, Can i please send the full statspack and the precamm function to your email??
Appreciate if you can really look into these
cheers


Tom Kyte
October 18, 2006 - 11:42 am UTC

trace it, see what it does.

do not send me a statspack, it would be useless.

tracing

dani, October 18, 2006 - 12:38 pm UTC

hi,
there are 32 tuxedo connections to the database and all those sessions are alive( i mean they dont disconnect, but remains connected). I can trace 1 such session.
But the sessons are very active i mean this db runs 400 trans per sec. How can i trace that function only??

Anyway I will put a trace on the session and tkprof to see what i get.
Cheers


Tom Kyte
October 18, 2006 - 1:13 pm UTC

you mean your code isn't set up to be debugged, maintained, tuned???

Be a good time to fix that - it should be EASY to trace things, not hard.

correction

dani, October 18, 2006 - 1:11 pm UTC

Tom,
Sorry what i think you mean is use dbms profiler to trace.
I will do that.
I just happened to talk to the programmer and what i understand is that that specific function when called so many times , it is internally calling a procedure with passing a value n, where n is like 4,5,6 etv.
That procedure is called delay and its job is to create a delay in the logic flow. So the delay procedure accepsts values like 10 as seconds and then it
FOR di IN 1..sed LOOP
NULL;
END LOOP;
A random thought, could this when run so many times accumulate huge cpu? if yes could we use sleep plsql function if that does not spin cpu?
I wil in any case run a profile to see.Objective is to find the cpu consumign part in the precam function.
cheers



Tom Kyte
October 18, 2006 - 3:40 pm UTC

oh
my
gosh



oh
my
gosh


ouch, ouch, ouch, OUCH....

dbms_lock.sleep(1);

that would not work?????????????????????????


oh man, my head hurts too bad from this one.

oh my gosh, ouch, ouch, ouch.


Does this programmer have a side job with the guys that sell you cpu?

tight loop withNULL - better get liquid cooled CPU's

John Stegeman, October 18, 2006 - 3:07 pm UTC

Hi Dani,

The loop as you have it coded in the review right above

for x in 1..n loop
null;
end loop;

will definitely chew up cpu. DBMS_LOCK should be more friendly to the cpu's.


:-)

dani, October 18, 2006 - 7:46 pm UTC

Tom,
I have now been informed about the actual reason as to why did they code the delay and am afraid the reason is such that I can not share it on here, I means its public, i can send you the reason for your curiosity if u have an email add.
I have now given the application schema the execcute privilege on the dbms_lock proc. They will change that delay to dnms_lock.sleep (their delay varies from 10 sec to 59 secs).
Yes in actual face they still want a delay for the same reason. I wish if i had a solution for them.
I will let you know how thing s went in terms of cpu usage after the sleep proc. I mean this would take atleast a week before the chane would move to prod after uat and proper change control approval. I hope that the cpu would drastically come down and this would really go in my favour for the cpu license savings.

performance improved

daniel, November 02, 2006 - 7:54 am UTC

Hi tom,
After converting the for loop to sleep procedure, the darabase shows 53% cpu reduction. and this affects the os which reduced almost 36.2 cpu. From statspack the cpu secs were reduced to 53% exactly.
Thanks for your tip.
Questions:
When using dbms profiler, I see results for every line of the procedure with the time elapsed. What I wanted is to find out the CPU secs consumed by that procedure or(the block of code inside that procedure) and not the elapsed time which could be due to an i.o as well.
My objective is to breakup any plsqlp procedureand find out areas where the code is taking cpu time. How do i do that??

In reference to another document where i posted my question about pl.sql native, what i have noticed is that on a really high end machine, the plsql native compilation really does not provide much signifincat improvment even if the underlyign procdues contais more logic (than sql) and even if its 5000 lines of code. Now your example which shows imprvment but in reality people do not use that kind of code in databas procedurs, so really the plsql native compilation with the practical approach to say 90% of the applicationis really a myth, better to upgrade to 10g.

Cheers





Tom Kyte
November 02, 2006 - 8:11 am UTC

if you check out proftab.sql in $ORACLE_HOME/rdbms/admin - you'll see there is no "cpu" times available.

native compilation is not a myth, it is just that many people imagine it'll give them orders of magnitude improvements, when tens of percents improvements is much more likely (eg: it can definitely improve performance, it will not however make it run in 1/10th the time)

Who last compiled the package?

Deepak Gulrajani, November 02, 2006 - 8:05 pm UTC

Tom, Is there any Oracle meta-data table/view by which we can know the Operating System User Name(linux/unix or Windows User) of the person who last compiled an object(let's say a package) in the Oracle Database 10G via a windows client or a linux client.
Thanks,
Deepak

Tom Kyte
November 02, 2006 - 9:14 pm UTC

if you use an alter and create DDL trigger, you can catch *some* of them (not implicit recompiles that just happen)

Native Compiling error when use FOR

Danijel Vukovic, April 11, 2007 - 7:01 am UTC

Hi Tom,

I have one problem when i compiling package. This is for statement that doesn't work in compiling

for i in (select d.id, d.value1 from dv_rn_tb1 d where d.id in(1,2,4,6,8,9,4))
loop
dbms_output.put_line('test'||to_char(i.value1));
end loop;

This for statemen works
for i in 1..100
loop
dbms_output.put_line('test'||to_char(i));
end loop;
runstats_pkg.rs_stop();

Message i recive is when i execute "show Error" is "No errors"

Regards
Dani

Tom Kyte
April 11, 2007 - 11:29 am UTC

how about

show errors package body PKG_NAME


please replace pkg_name with, well, your package name :)

and provide full tests that we can run if you want us to look at it. We do not have your table for example.


(because when you whittle the problem down to the smallest thing possible to reproduce the error - 99999999 times out of 100000000, you'll find your own mistake making the test case!)

Native Compiling error when use FOR

Dani, April 20, 2007 - 9:07 am UTC

Table
create table DV_RN_TB1
(
ID INTEGER,
VALUE1 INTEGER
);

insert into dv_rn_tb1 values (1,89);
insert into dv_rn_tb1 values (2,78);
insert into dv_rn_tb1 values (3,67);
insert into dv_rn_tb1 values (4,7);
insert into dv_rn_tb1 values (5,5);
insert into dv_rn_tb1 values (6,34);
insert into dv_rn_tb1 values (7,33);
insert into dv_rn_tb1 values (8,20);
insert into dv_rn_tb1 values (9,10);
insert into dv_rn_tb1 values (10,9);
Package
create or replace package DV_TEST2 as
procedure equal_number_hsl_case;
end DV_TEST2;

create or replace package body DV_TEST2 is
procedure equal_number_hsl_case is
x number;
y number;
begin
--run this does not work
for i in (select d.id, d.value1 from dv_rn_tb1 d where d.id in(1,2,4,6,8,9,4))
loop
dbms_output.put_line('test'||to_char(i.value1));
end loop;
-- or this this works fine
for i in 1..100
loop
dbms_output.put_line('test'||to_char(i));
end loop;
end;
end DV_TEST2;

Native compiling of package return error.
SQL> alter session set plsql_code_type = 'NATIVE';
Session altered
SQL> alter package dv_test2 compile package;
Warning: Package altered with compilation errors
SQL> show errors;
No errors for PACKAGE DANI.DV_TEST2

Thanks Tom

Regards Dani
Tom Kyte
April 20, 2007 - 10:24 am UTC

I cannot reproduce.


ops$tkyte%ORA9IR2> alter system set plsql_native_make_utility = 'make';

System altered.

ops$tkyte%ORA9IR2> alter system set plsql_native_make_file_name = '/home/ora9ir2/plsql/spnc_makefile.mk';

System altered.

ops$tkyte%ORA9IR2> alter session set plsql_compiler_flags = 'INTERPRETED';

Session altered.

ops$tkyte%ORA9IR2> alter system set plsql_native_library_dir = '/tmp';

System altered.

ops$tkyte%ORA9IR2> alter session set plsql_compiler_flags = 'NATIVE';

Session altered.

ops$tkyte%ORA9IR2> alter package dv_test2 compile;

Package altered.

ops$tkyte%ORA9IR2> show errors package dv_test2;
No errors.
ops$tkyte%ORA9IR2>
ops$tkyte%ORA9IR2> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.8.0 - Production
PL/SQL Release 9.2.0.8.0 - Production
CORE    9.2.0.8.0       Production
TNS for Linux: Version 9.2.0.8.0 - Production
NLSRTL Version 9.2.0.8.0 - Production



SYS.DBMS_CDC_PUBLISH

Fayyaz, April 23, 2007 - 7:10 am UTC

*** string too long, truncated *** (18863), ORA-06502: PL/SQL: numeric or value error: character string buffer too small
I got below error on our Production database.
Two three weeks back we got the ORA-00600 error and we raised the SR with ORACLE. The woraround they have given is, disable the four trigger related to DBMS_CDC_*

Can you please explain, how can we overcome this error?
What is the purpose of these CDC triggers?

Thanks in advance
Fayyaz

*** 2007-04-23 09:19:13.341
*** SESSION ID:(1263.5641) 2007-04-23 09:19:13.340
ORA-00604: error occurred at recursive SQL level 3
ORA-00028: your session has been killed
ORA-06512: at "SYS.DBMS_CDC_PUBLISH", line 325
ORA-06512: at line 3
CREATE GLOBAL TEMPORARY TABLE "SYS"."SYS_TEMP_0FD9D6BA6_3539A72C" ("C0" ROWID,"C1" VARCHAR2(15),"C2" VARCHAR2(10),"C3" VARCHAR2(10),"C4" VARCHAR2(3),"C5" VARCHAR2(3),"C6" VARCHAR2(10),"C7" VARCHAR2(10),"C8" VARCHAR2(10),"C9" VARCHAR2(3),"C10" VARCHAR2(3) ) IN_MEMORY_METADATA CURSOR_SPECIFIC_SEGMENT STORAGE (OBJNO 4254952358 ) NOPARALLEL
Current SQL statement for this session:
/* MV_REFRESH (MRG) */ MERGE INTO "SCE"."MV_PARTNER_LOCATOR" "SNA$" USING ( WITH TMPDLT$_PARTNER_PROFILE AS ( SELECT "MAS$"."RID$" "RID$" , "MAS$"."SHORT_NAME", "MAS$"."PARTNER_STATUS", "MAS$"."PARTNER_INTERFACE", "MAS$"."ACTIVE_PARTNER", "MAS$"."COMPANY_CODE", "MAS$"."OWNER_CODE", "MAS$"."OWNER_SUB_CODE", "MAS$"."PARTNER_CODE", "MAS$"."PARTNER_SUB_CODE", DECODE("MAS$"."OLD_NEW$$", 'N', 'I', 'D') "DML$$" FROM (SELECT "MAS$".*, MIN("MAS$"."SEQ$$") OVER (PARTITION BY "MAS$"."RID$") "MINSEQ$$", MAX("MAS$"."SEQ$$") OVER (PARTITION BY "MAS$"."RID$") "MAXSEQ$$" FROM (SELECT /*+ CARDINALITY(MAS$ 2) */ CHARTOROWID("MAS$"."M_ROW$$") RID$ , "MAS$"."SHORT_NAME", "MAS$"."PARTNER_STATUS", "MAS$"."PARTNER_INTERFACE", "MAS$"."ACTIVE_PARTNER", "MAS$"."COMPANY_CODE", "MAS$"."OWNER_CODE", "MAS$"."OWNER_SUB_CODE", "MAS$"."PARTNER_CODE", "MAS$"."PARTNER_SUB_CODE" , "MAS$"."SEQUENCE$$" "SEQ$$", "MAS$"."OLD_NEW$$" "OLD_NEW$$" FROM "SCE"."MLOG$_PARTNER_PROFILE" "MAS$" WHERE "MAS$".SNAPTIME$$ > :2 ) "MAS$" ) "MAS$" WHERE ((("MAS$"."OLD_NEW$$" = 'N') AND ("MAS$"."SEQ$$" = "MAS$"."MAXSEQ$$")) OR (("MAS$"."OLD_NEW$$" IN ('O', 'U')) AND ("MAS$"."SEQ$$" = "MAS$"."MINSEQ$$"))) ) , TMPDLT$_PARTNERS AS ( SELECT "MAS$"."RID$" "RID$" , "MAS$"."PARTNER_UID", "MAS$"."PARTNER_CODE", "MAS$"."PARTNER_SUB_CODE", "MAS$"."COMPANY_CODE", "MAS$"."OWNER_CODE", "MAS$"."OWNER_SUB_CODE", "MAS$"."FULL_NAME", "MAS$"."DELETE_FLAG", DECODE("MAS$"."OLD_NEW$$", 'N', 'I', 'D') "DML$$" FROM (SELECT "MAS$".*, MIN("MAS$"."SEQ$$") OVER (PARTITION BY "MAS$"."RID$") "MINSEQ$$", MAX("MAS$"."SEQ$$") OVER (PARTITION BY "MAS$"."RID$") "MAXSEQ$$" FROM (SELECT /*+ CARDINALITY(MAS$ 2) */ CHARTOROWID("MAS$"."M_ROW$$") RID$ , "MAS$"."PARTNER_UID", "MAS$"."PARTNER_CODE", "MAS$"."PARTNER_SUB_CODE", "MAS$"."COMPANY_CODE", "MAS$"."OWNER_CODE", "MAS$"."OWNER_SUB_CODE", "MAS$"."FULL_NAME", "MAS$"."DELETE_FLAG" , "MAS$"."SEQUENCE$$" "SEQ$$", "MAS$"."OLD_NEW$$" "OLD_NEW$$" FROM "SCE"."MLOG$_PARTNERS" "MAS$" WHERE "MAS$".SNAPTIME$$ > :3 ) "MAS$" ) "MAS$" WHERE ((("MAS$"."OLD_NEW$$" = 'N') AND ("MAS$"."SEQ$$" = "MAS$"."MAXSEQ$$")) OR (("MAS$"."OLD_NEW$$" IN ('O', 'U')) AND ("MAS$"."SEQ$$" = "MAS$"."MINSEQ$$"))) ) SELECT /*+ MAX_CARDINALITY(96758) */ "DV$"."GB0" "GB0", "DV$"."GB1" "GB1", "DV$"."GB2" "GB2", "DV$"."GB3" "GB3", "DV$"."GB4" "GB4", "DV$"."GB5" "GB5", "DV$"."GB6" "GB6", "DV$"."GB7" "GB7", "DV$"."GB8" "GB8", "DV$"."GB9" "GB9", "DV$"."GB10" "GB10", "DV$"."GB11" "GB11", "DV$"."GB12" "GB12", "DV$"."GB13" "GB13", "DV$"."GB14" "GB14", "DV$"."GB15" "GB15", "DV$"."GB16" "GB16", "DV$"."GB17" "GB17", "DV$"."GB18" "GB18", "DV$"."GB19" "GB19", "DV$"."GB20" "GB20", "DV$"."GB21" "GB21", "DV$"."GB22" "GB22", "DV$"."GB23" "GB23", SUM(DECODE("DV$"."DML$$", 'I', 1, -1)) "D0" FROM ( ( SELECT /*+ */ "PRE$3"."PARTNER_UID" "GB0", "PRE$3"."PARTNER_CODE" "GB1", "PRE$3"."PARTNER_SUB_CODE" "GB2", "PRE$3"."COMPANY_CODE" "GB3", "PRE$3"."OWNER_CODE" "GB4", "PRE$3"."OWNER_SUB_CODE" "GB5", "PRE$3"."FULL_NAME" "GB6", "PRE$2"."SHORT_NAME" "GB7", "PRE$2"."PARTNER_STATUS" "GB8", "PRE$2"."PARTNER_INTERFACE" "GB9", "PRE$2"."ACTIVE_PARTNER" "GB10", "MAS$1"."ADDRESS_TYPE" "GB11", "MAS$1"."ADDR_CODE" "GB12", "MAS$1"."ADDR_NUMBER" "GB13", "DLT$0"."FULL_NAME" "GB14", "DLT$0"."ADDRESS_1" "GB15", "DLT$0"."ADDRESS_2" "GB16", "DLT$0"."ADDRESS_3" "GB17", "DLT$0"."ADDRESS_4" "GB18", "DLT$0"."ADDRESS_5" "GB19", "DLT$0"."POINT_CODE" "GB20", "DLT$0"."COUNTY_STATE_CODE" "GB21", "DLT$0"."POST_CODE" "GB22", "DLT$0"."COUNTRY" "GB23", "DLT$0".DML$$ DML$$ FROM (SELECT /*+ CARDINALITY(MAS$ 2) */ CHARTOROWID("MAS$"."M_ROW$$") RID$ , "MAS$"."FULL_NAME", "MAS$"."ADDRESS_1", "MAS$"."ADDRESS_2", "MAS$"."ADDRESS_3", "MAS$"."ADDRESS_4", "MAS$"."ADDRESS_5", "MAS$"."POINT_CODE", "MAS$"."COUNTY_STATE_CODE", "MAS$"."POST_CODE", "MAS$"."COUNTRY", "MAS$"."ADDR_CODE" , DECODE("MAS$".OLD_NEW$$, 'N', 'I', 'D') DML$$ FROM "SCE"."MLOG$_ADDRESSES" "MAS$" WHERE "MAS$".SNAPTIME$$ > :1 ) "DLT$0" , (SELECT "MAS$"."ROWID" "RID$" , "MAS$"."ADDRESS_TYPE", "MAS$"."ADDR_CODE", "MAS$"."ADDR_NUMBER", "MAS$"."COMPANY_CODE", "MAS$"."PARTNER_CODE", "MAS$"."PARTNER_SUB_CODE", "MAS$"."OWNER_CODE", "MAS$"."OWNER_SUB_CODE", "MAS$"."DELETE_FLAG" FROM "SCE"."PARTNERS_ADDRESSES" "MAS$") AS OF SNAPSHOT (:4) "MAS$1" , (SELECT /*+ CARDINALITY(MAS$ 1) */ "MAS$"."RID$" "RID$" , "MAS$"."SHORT_NAME", "MAS$"."PARTNER_STATUS", "MAS$"."PARTNER_INTERFACE", "MAS$"."ACTIVE_PARTNER", "MAS$"."COMPANY_CODE", "MAS$"."OWNER_CODE", "MAS$"."OWNER_SUB_CODE", "MAS$"."PARTNER_CODE", "MAS$"."PARTNER_SUB_CODE" FROM "TMPDLT$_PARTNER_PROFILE" "MAS$" WHERE "MAS$"."DML$$" = 'D' ) "PRE$2" , (SELECT /*+ CARDINALITY(MAS$ 1) */ "MAS$"."RID$" "RID$" , "MAS$"."PARTNER_UID", "MAS$"."PARTNER_CODE", "MAS$"."PARTNER_SUB_CODE", "MAS$"."COMPANY_CODE", "MAS$"."OWNER_CODE", "MAS$"."OWNER_SUB_CODE", "MAS$"."FULL_NAME", "MAS$"."DELETE_FLAG" FROM "TMPDLT$_PARTNERS" "MAS$" WHERE "MAS$"."DML$$" = 'D' ) "PRE$3" WHERE ("DLT$0"."ADDR_CODE"="MAS$1"."ADDR_CODE" AND "MAS$1"."COMPANY_CODE"="PRE$3"."COMPANY_CODE" AND "MAS$1"."PARTNER_CODE"="PRE$3"."PARTNER_CODE" AND "MAS$1"."PARTNER_SUB_CODE"="PRE$3"."PARTNER_SUB_CODE" AND "MAS$1"."OWNER_CODE"="PRE$3"."OWNER_CODE" AND "MAS$1"."OWNER_SUB_CODE"="PRE$3"."OWNER_SUB_CODE" AND NVL("MAS$1"."DELETE_FLAG",'N')<>'Y' AND UPPER(NVL("PRE$2"."PARTNER_STATUS",'N'))<>'ON HOLD' AND "PRE$3"."COMPANY_CODE"="PRE$2"."COMPANY_CODE" AND "PRE$3"."OWNER_CODE"="PRE$2"."OWNER_CODE" AND "PRE$3"."OWNER_SUB_CODE"="PRE$2"."OWNER_SUB_CODE" AND "PRE$3"."PARTNER_CODE"="PRE$2"."PARTNER_CODE" AND "PRE$3"."PARTNER_SUB_CODE"="PRE$2"."PARTNER_SUB_CODE" AND "PRE$3"."DELETE_FLAG"<>'Y') ) UNION ALL ( SELECT /*+ */ "PRE$3"."PARTNER_UID" "GB0", "PRE$3"."PARTNER_CODE" "GB1", "PRE$3"."PARTNER_SUB_CODE" "GB2", "PRE$3"."COMPANY_CODE" "GB3", "PRE$3"."OWNER_CODE" "GB4", "PRE$3"."OWNER_SUB_CODE" "GB5", "PRE$3"."FULL_NAME" "GB6", "PRE$2"."SHORT_NAME" "GB7", "PRE$2"."PARTNER_STATUS" "GB8", "PRE$2"."PARTNER_INTERFACE" "GB9", "PRE$2"."ACTIVE_PARTNER" "GB10", "MAS$1"."ADDRESS_TYPE" "GB11", "MAS$1"."ADDR_CODE" "GB12", "MAS$1"."ADDR_NUMBER" "GB13", "DLT$0"."FULL_NAME" "GB14", "DLT$0"."ADDRESS_1" "GB15", "DLT$0"."ADDRESS_2" "GB16", "DLT$0"."ADDRESS_3" "GB17", "DLT$0"."ADDRESS_4" "GB18", "DLT$0"."ADDRESS_5" "GB19", "DLT$0"."POINT_CODE" "GB20", "DLT$0"."COUNTY_STATE_CODE" "GB21", "DLT$0"."POST_CODE" "GB22", "DLT$0"."COUNTRY" "GB23", "DLT$0".DML$$ DML$$ FROM (SELECT /*+ CARDINALITY(MAS$ 2) */ CHARTOROWID("MAS$"."M_ROW$$") RID$ , "MAS$"."FULL_NAME", "MAS$"."ADDRESS_1", "MAS$"."ADDRESS_2", "MAS$"."ADDRESS_3", "MAS$"."ADDRESS_4", "MAS$"."ADDRESS_5", "MAS$"."POINT_CODE", "MAS$"."COUNTY_STATE_CODE", "MAS$"."POST_CODE", "MAS$"."COUNTRY", "MAS$"."ADDR_CODE" , DECODE("MAS$".OLD_NEW$$, 'N', 'I', 'D') DML$$ FROM "SCE"."MLOG$_ADDRESSES" "MAS$" WHERE "MAS$".SNAPTIME$$ > :1 ) "DLT$0" , (SELECT "MAS$"."ROWID" "RID$" , "MAS$"."ADDRESS_TYPE", "MAS$"."ADDR_CODE", "MAS$"."ADDR_NUMBER", "MAS$"."COMPANY_CODE", "MAS$"."PARTNER_CODE", "MAS$"."PARTNER_SUB_CODE", "MAS$"."OWNER_CODE", "MAS$"."OWNER_SUB_CODE", "MAS$"."DELETE_FLAG" FROM "SCE"."PARTNERS_ADDRESSES" "MAS$") AS OF SNAPSHOT (:4) "MAS$1" , (SELECT "MAS$"."ROWID" "RID$" , "MAS$"."SHORT_NAME", "MAS$"."PARTNER_STATUS", "MAS$"."PARTNER_INTERFACE", "MAS$"."ACTIVE_PARTNER", "MAS$"."COMPANY_CODE", "MAS$"."OWNER_CODE", "MAS$"."OWNER_SUB_CODE", "MAS$"."PARTNER_CODE", "MAS$"."PARTNER_SUB_CODE" FROM "SCE"."PARTNER_PROFILE" "MAS$") "PRE$2" , (SELECT /*+ CARDINALITY(MAS$ 1) */ "MAS$"."RID$" "RID$" , "MAS$"."PARTNER_UID", "MAS$"."PARTNER_CODE", "MAS$"."PARTNER_SUB_CODE", "MAS$"."COMPANY_CODE", "MAS$"."OWNER_CODE", "MAS$"."OWNER_SUB_CODE", "MAS$"."FULL_NAME", "MAS$"."DELETE_FLAG" FROM "TMPDLT$_PARTNERS" "MAS$" WHERE "MAS$"."DML$$" = 'D' ) "PRE$3" WHERE ("DLT$0"."ADDR_CODE"="MAS$1"."ADDR_CODE" AND "MAS$1"."COMPANY_CODE"="PRE$3"."COMPANY_CODE" AND "MAS$1"."PARTNER_CODE"="PRE$3"."PARTNER_CODE" AND "MAS$1"."PARTNER_SUB_CODE"="PRE$3"."PARTNER_SUB_CODE" AND "MAS$1"."OWNER_CODE"="PRE$3"."OWNER_CODE" AND "MAS$1"."OWNER_SUB_CODE"="PRE$3"."OWNER_SUB_CODE" AND NVL("MAS$1"."DELETE_FLAG",'N')<>'Y' AND UPPER(NVL("PRE$2"."PARTNER_STATUS",'N'))<>'ON HOLD' AND "PRE$3"."COMPANY_CODE"="PRE$2"."COMPANY_CODE" AND "PRE$3"."OWNER_CODE"="PRE$2"."OWNER_CODE" AND "PRE$3"."OWNER_SUB_CODE"="PRE$2"."OWNER_SUB_CODE" AND "PRE$3"."PARTNER_CODE"="PRE$2"."PARTNER_CODE" AND "PRE$3"."PARTNER_SUB_CODE"="PRE$2"."PARTNER_SUB_CODE" AND "PRE$3"."DELETE_FLAG"<>'Y') AND SYS_OP_MAP_NONNULL("PRE$2"."RID$") NOT IN (SELECT /*+ CARDINALITY(MAS$ 1) ANTIJOIN */ SYS_OP_MAP_NONNULL("MAS$"."RID$") "RID$" FROM "TMPDLT$_PARTNER_PROFILE" "MAS$" WHERE "MAS$"."DML$$" = 'I' ) ) UNION ALL ( SELECT /*+ */ "PRE$3"."PARTNER_UID" "GB0", "PRE$3"."PARTNER_CODE" "GB1", "PRE$3"."PARTNER_SUB_CODE" "GB2", "PRE$3"."COMPANY_CODE" "GB3", "PRE$3"."OWNER_CODE" "GB4", "PRE$3"."OWNER_SUB_CODE" "GB5", "PRE$3"."FULL_NAME" "GB6", "PRE$2"."SHORT_NAME" "GB7", "PRE$2"."PARTNER_STATUS" "GB8", "PRE$2"."PARTNER_INTERFACE" "GB9", "PR...

native

Danijel Vukovic, April 25, 2007 - 6:07 am UTC

Hi Tom,

I use v10:
SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production

TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production


I use MinGW for C compiling. Is the enought informations.
I work under Windows XP.

Thanks Tom ,

Regards Dani
Tom Kyte
April 25, 2007 - 10:11 am UTC

enough information for what?

It is enough information for you to tell me that you use version 10.2.0.1 on Windows XP and like to compile C with MinGW.

But beyond that - it is insufficient to do anything else.

I presume you are having a problem with native compilation, MinGW is not the supported C compiled on Windows - Microsoft compilers are. It will not be supported/supportable any other way. This will not be worth your effort to try and hack it into working.

Compile

Danijel Vukovic, April 30, 2007 - 3:19 am UTC

Hy Tom,

I compile in Oracle 10g.
SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production

TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production

Maybe is this a problem.
Tom Kyte
April 30, 2007 - 9:38 am UTC

maybe WHAT is a problem? You have yet to describe any problem - you have said "I have a problem" but you don't really say......

what it is.

I can say that compiler is not one that we use on windows - so perhaps whatever your problem is - it is related to that fact.

11g native compilation

A reader, May 25, 2007 - 3:36 pm UTC

Tom, read recently about 11g native compilation improvements. In one of your previous replies you said that it can be even worse to convert some user function that is called from SQL into natively compiled due to the double context switch (sql-plsql-native) - at least that was my understanding of your answer. Is it still true in 11g?
Tom Kyte
May 26, 2007 - 12:14 pm UTC

in 11g native compilation will be so much easier to turn on and use (no need for a compiler to be installed, configured and all)

so the ability to native compile everything will exist in an easy fashion...

so the non-native calling native stuff won't be a problem in that case.

Helena Marková, May 30, 2007 - 4:06 am UTC


Native Compilation in 11g

Zahir M, April 21, 2008 - 1:27 pm UTC

In one of my 11g databases , 
I changed copilation mode from  'INTERPRETED' to 'NATIVE' by executing 
dbmsupgnv in upgrade mode ... 

Still some of the packages are in INTERPRETED mode . 
Why would some be in INTERPRETED while others are in NATIVE . Please advise.





  1  SELECT TYPE, PLSQL_CODE_TYPE, COUNT(*)
  2    FROM DBA_PLSQL_OBJECT_SETTINGS
  3    WHERE PLSQL_CODE_TYPE IS NOT NULL
  4    GROUP BY TYPE, PLSQL_CODE_TYPE
  5*   ORDER BY TYPE, PLSQL_CODE_TYPE
SQL> 
SQL> /

TYPE         PLSQL_CODE_TYPE                  COUNT(*)
------------ ------------------------------ ----------
FUNCTION     NATIVE                                414
PACKAGE      INTERPRETED                          1318
PACKAGE      NATIVE                                  2
PACKAGE BODY NATIVE                               1258
PROCEDURE    NATIVE                                455
TRIGGER      NATIVE                               1075
TYPE         INTERPRETED                          2311
TYPE         NATIVE                                243
TYPE BODY    NATIVE                                224

9 rows selected.


  1  Select * from (
  2  SELECT owner , NAME , TYPE
  3   FROM all_plsql_object_settings WHERE plsql_code_type <> 'NATIVE'
  4* ) where rownum < 10
SQL> /

OWNER                          NAME                           TYPE
------------------------------ ------------------------------ ------------
SYS                            AGGXMLIMP                      TYPE
SYS                            AGGXQAVGIMP                    TYPE
SYS                            AGGXQIMP                       TYPE
SYS                            AGGXQSUMIMP                    TYPE
SYS                            ALERT_TYPE                     TYPE
SYS                            ANYDATA                        TYPE
SYS                            ANYDATASET                     TYPE
SYS                            ANYTYPE                        TYPE
SYS                            AQ$_AGENT                      TYPE

9 rows selected.





  1  Select * from (
  2  SELECT owner , NAME , TYPE
  3   FROM all_plsql_object_settings WHERE plsql_code_type = 'NATIVE'
  4* ) where rownum < 10
SQL> /

OWNER                          NAME                           TYPE
------------------------------ ------------------------------ ------------
SYS                            ANYDATA                        TYPE BODY
SYS                            ANYDATASET                     TYPE BODY
SYS                            ANYTYPE                        TYPE BODY
SYS                            APS_VALIDATE                   PROCEDURE
SYS                            AQ$_GET_SUBSCRIBERS            FUNCTION
SYS                            AQ$_JMS_BYTES_MESSAGE          TYPE BODY
SYS                            AQ$_JMS_HEADER                 TYPE BODY
SYS                            AQ$_JMS_MAP_MESSAGE            TYPE BODY
SYS                            AQ$_JMS_MESSAGE                TYPE BODY

9 rows selected.

compilation interpretation and execution in pl/sql

Vamshi, June 18, 2008 - 6:10 am UTC

Hai Tom,

Can you Please Explain me How a PLSQL block compiles,interprets and executes and into what code they are converted in detail?

Thanks in Advance

Tom Kyte
June 18, 2008 - 2:36 pm UTC

in detail consists of this:

a) block is submitted
b) block is parsed into a parse tree
c) block is compiled into byte code - just like the newer language java is
d) byte code is interpreted in a virtual machine


that is all - it is just like any other compiled language. We can also take step C and have block be compiled into native operating system byte code and run by the OS - just like java and other languages do.

Attempt to benchmark gain from PL/SQL native compilation

Scott Duncan, January 19, 2009 - 2:50 pm UTC

Hi Tom,

As I have been asked to benchmark the performance gain to our Fund Management application trade profit and loss processing ( which is quite processing intensive ) by using plsql native compilation, I have installed a Microsoft Visual Studio 2008 C++ compiler ( amd64 cl.exe )on my benchmark server. The server has Oracle 10.2.0.4 on Windows 2003 R2 Standard x64 Edition SP2.

Initially I am simply attempting to compile a basic 'Hello World' procedure and it is failing to find the dll although the dll appears to be being created ok in the appropriate folder defined by the param plsql_native_library_dir.

e.g.
alter session set plsql_code_type='NATIVE';

create or replace procedure my_test_x is
begin
dbms_output.put_line('hello world');
end;

select * from user_errors

ORA-06549: PL/SQL: failed to dynamically open shared object (DLL): The specified module could not be found.

After having problems with calling cl.exe directly in spnc_command file, I have configured spnc_command file to to call a batch file ncomp_compile.bat passing %(src) %(obj) %(dll) args and this is creating the
.dll sucessfully. The contents of this bat file are as follows :

call "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat" amd64
"C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\amd64\cl.exe" %1 /nologo /Zm200
/Og /Oy /MD /Fo%2 /IC:\Oracle\Ora102/plsql/public
/IC:\Oracle\Ora102/plsql/include /link /nologo /dll
C:\Oracle\Ora102/lib/orapls10.lib /out:%3;
exit;

In summary, the problem I am now having is that Oracle reports error : ORA-06549: PL/SQL: failed to dynamically open shared object (DLL): The specified module could not be found.

I have tried to investigate on metalink, google etc.. and have not been able to determine what is causing this error. I am guessing that it may be an x64 issue or it may be related to environment vars. I have just raised an SR with Oracle also. There seems to be quite limited docs and forums etc on native compilation, particularly on Windows x64.

Any help or advice you can offer on what may causing this failure would be hugely appreciated.

Thanks in advance,

Scott Duncan

Performance of native plsql compilation

Scott Duncan, January 19, 2009 - 3:00 pm UTC

Hi Tom,

As I have been asked to benchmark the performance gain to our Fund Management application trade profit and loss processing ( which is quite processing intensive ) by using plsql native compilation, I have installed a Microsoft Visual Studio 2008 C++ compiler ( amd64 cl.exe )on my benchmark server. The server has Oracle 10.2.0.4 on Windows 2003 R2 Standard x64 Edition SP2.

Initially I am simply attempting to compile a basic 'Hello World' procedure and it is failing to find the dll although the dll appears to be being created ok in the appropriate folder defined by the param plsql_native_library_dir.

e.g.
alter session set plsql_code_type='NATIVE';

create or replace procedure my_test_x is
begin
dbms_output.put_line('hello world');
end;

select * from user_errors

ORA-06549: PL/SQL: failed to dynamically open shared object (DLL): The specified module could not be found.

After having problems with calling cl.exe directly in spnc_command file, I have configured spnc_command file to to call a batch file ncomp_compile.bat passing %(src) %(obj) %(dll) args and this is creating the
.dll sucessfully. The contents of this bat file are as follows :

call "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat" amd64
"C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\amd64\cl.exe" %1 /nologo /Zm200
/Og /Oy /MD /Fo%2 /IC:\Oracle\Ora102/plsql/public
/IC:\Oracle\Ora102/plsql/include /link /nologo /dll
C:\Oracle\Ora102/lib/orapls10.lib /out:%3;
exit;

In summary, the problem I am now having is that Oracle reports error : ORA-06549: PL/SQL: failed to dynamically open shared object (DLL): The specified module could not be found.

I have tried to investigate on metalink, google etc.. and have not been able to determine what is causing this error. I am guessing that it may be an x64 issue or it may be related to environment vars. I have just raised an SR with Oracle also. There seems to be quite limited docs and forums etc on native compilation, particularly on Windows x64.

Any help or advice you can offer on what may causing this failure would be hugely appreciated.

Thanks in advance,

Scott Duncan

trying get a measure of gain from natively compiling pl/sql

Scott Duncan, January 20, 2009 - 5:32 am UTC

Hi Tom, my post is being deleted but I am confused as it seemed to me that trying to benchmark the performance gain I can get from native pl/sql is totally relevant to the original question. If I can get it to compile ok I will be delighted to feedback the results which should help to give a real world feedback to the original question. My post is as follows below, please can you re-consider that it is very relevant. Thanks.

---- original post ----

I have been asked to benchmark the performance gain to our Fund Management application trade profit and loss processing ( which is quite processing intensive ) by using plsql native compilation. I have installed a Microsoft Visual Studio 2008 C++ compiler ( amd64 cl.exe )on my benchmark server. The server has Oracle 10.2.0.4 on Windows 2003 R2 Standard x64 Edition SP2.

Initially I am simply attempting to compile a basic 'Hello World' procedure and it is failing to find the dll although the dll appears to be being created ok in the appropriate folder defined by the param plsql_native_library_dir.

e.g.
alter session set plsql_code_type='NATIVE';

create or replace procedure my_test_x is
begin
dbms_output.put_line('hello world');
end;

select * from user_errors

ORA-06549: PL/SQL: failed to dynamically open shared object (DLL): The specified module could not be found.

After having problems with calling cl.exe directly in spnc_command file, I have configured spnc_command file to to call a batch file ncomp_compile.bat passing %(src) %(obj) %(dll) args and this is creating the
.dll sucessfully. The contents of this bat file are as follows :

call "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcvarsall.bat" amd64
"C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\amd64\cl.exe" %1 /nologo /Zm200
/Og /Oy /MD /Fo%2 /IC:\Oracle\Ora102/plsql/public
/IC:\Oracle\Ora102/plsql/include /link /nologo /dll
C:\Oracle\Ora102/lib/orapls10.lib /out:%3;
exit;

In summary, the problem I am now having is that Oracle reports error : ORA-06549: PL/SQL: failed to dynamically open shared object (DLL): The specified module could not be found.

I have tried to investigate on metalink, google etc.. and have not been able to determine what is causing this error. I am guessing that it may be an x64 issue or it may be related to environment vars. I have just raised an SR with Oracle also. There seems to be quite limited docs and forums etc on native compilation, particularly on Windows x64.

Any help or advice you can offer on what may causing this failure would be hugely appreciated.

Thanks in advance,

Scott Duncan




Tom Kyte
January 20, 2009 - 7:21 am UTC

nothing has been deleted.

there is now three identical posts here.

I don't have a compiler on windows, I don't have a database on windows really..


It seems you are having an issue with the compiler - NOT with the procedure. That you are querying user errors shows the procedure compilation is failing (eg: the dll is NOT being created properly, this is not about not being able to invoke the dll you are looking at but rather that the dll is not being successfully generated)


Gain we obtained from pl/sql native compilation

Scott Duncan, January 26, 2009 - 7:38 am UTC

After difficulty with compilers Oracle confirmed that I the Intel 8.1 C++ compiler is definitely certified for 10g R2 native PL/SQL on Windows x64.

Sure enough having failed to get mingw gcc, Visual Studio 2008 C++ and Intel 11.0 ( current version ) to work I finally got an eval of the Intel 8.1 compiler via Intel support and found that it worked.

On the upside I was surprised that it was relatively quick and easy to compile our trading portfolio Fund Management application into native pl/sql.

On the downside I was surprised to find that it made almost no difference to performance. Of course it all depends what the app is doing. we thought that as there is some significant looping computational Profit and Loss logic that we would see at least e.g. 10% improvement but we didn't.

It almost made me wonder whether it's really running as native plsql but the dictionary tables indicate that it is via :

SELECT type, plsql_code_type, count(*)
FROM dba_plsql_object_settings
GROUP BY plsql_code_type, type

I have a repeatable automated test for thousands of trades and the result is marginally different. It was a tiny bit slower for a couple of trade types ( strange ) and tiny bit faster for others. Not much different at all.

Anyway, I have posted this review just to say that it does not always make much difference at all and also just in case you may feedback that we may have missed something and it may not be running as native correctly!! One obvious thing to me was that the instructions I followed have made the pkg bodies and type bodies as native but their specs have remained as INTERPRETED. I guess that means that there may still be a lot of context switching but as there's not a lot of code in specs I wouldn't expect natively compiling specs to make much difference? Any thoughts appreciated.

Thanks,

Scott Duncan

Tom Kyte
January 28, 2009 - 7:51 am UTC

... I guess
that means that there may still be a lot of context switching but as there's
not a lot of code in specs I wouldn't expect natively compiling specs to make
much difference? ...

you should do it all, yes. But I would not expect in general a large, huge difference. It would have to be some very computationally expensive plsql.

REGEXP Functions

Martin Rose, May 28, 2015 - 12:09 pm UTC

Tom,

i). the REGEXP functions are all written as PL/SQL routines, right? and assumedly are subject to context switching like any other PL/SQL functions ??

ii). If they were to be compiled natively, (not that it would eliminate the context switching), but would they run just as fast as if they had been written in C ? I'm guessing they would.

More to Explore

PL/SQL demos

Check out more PL/SQL tutorials on our LiveSQL tool.

PL/SQL docs

PL/SQL reference manual from the Oracle documentation library