Call now: 252-767-6166  
Oracle Training Oracle Support Development Oracle Apps

 E-mail Us
 Oracle Articles
New Oracle Articles

 Oracle Training
 Oracle Tips

 Oracle Forum
 Class Catalog

 Remote DBA
 Oracle Tuning
 Emergency 911
 RAC Support
 Apps Support
 Oracle Support

 SQL Tuning

 Oracle UNIX
 Oracle Linux
 Remote s
 Remote plans
 Application Server

 Oracle Forms
 Oracle Portal
 App Upgrades
 SQL Server
 Oracle Concepts
 Software Support

 Remote S


 Consulting Staff
 Consulting Prices
 Help Wanted!


 Oracle Posters
 Oracle Books

 Oracle Scripts

Don Burleson Blog 







Oracle compiled PL/SQL

Oracle Database Tips by Donald Burleson

Native compilation of PL/SQL

By default, PL/SQL code is compiled and stored in the form of byte code ready for execution.  During the execution process, this byte code is interpreted, a process which requires time and resources.  The process of native compilation converts PL/SQL stored procedures to Pro*C, which is then compiled to native code shared libraries, resulting in performance increases for the procedural code.    The extent of the performance increase depends on the content of the PL/SQL, with the best results shown in code containing lots of loops, logic, mathematical operations and comparatively less database work.

The setup required for native compilation depends on the version of Oracle being used. In Oracle 9i several parameters must be set and on some platforms the associated makefile may need adjustment, whereas Oracle 10g has made several parameters obsolete and the makefile rarely needs modification.

-- Oracle 9i setup.

ALTER SYSTEM SET plsql_native_make_utility = 'make';
ALTER SYSTEM SET plsql_native_make_file_name =
ALTER SYSTEM SET plsql_native_library_dir = '/u01/oradata/DB9I/native';

-- Oracle 10g setup.
ALTER SYSTEM SET plsql_native_library_dir = '/u01/oradata/DB10G/native'

Notice that the directory used to hold the shared libraries is database-specific to prevent issues when multiple instances are running on a single server.

Once these parameters are set the compilation style can be switched by setting session or instance level parameters.

-- Oracle 9i switch.

ALTER SESSION SET plsql_compiler_flags = 'INTERPRETED';
ALTER SESSION SET plsql_compiler_flags = 'NATIVE';

ALTER SYSTEM SET plsql_compiler_flags = 'INTERPRETED';
ALTER SYSTEM SET plsql_compiler_flags = 'NATIVE';

-- Oracle 10g switch.

ALTER SESSION SET plsql_code_type = 'NATIVE';

ALTER SYSTEM SET plsql_code_type = 'NATIVE';

The test_speed.sql script creates a procedure, which we will use to test the performance gains associated with native compilation.


  l_number  NUMBER;
  FOR i IN 1 .. 1000000 LOOP
    l_number := i / 1000;

With the procedure compiled we can compare the speed using the native_comp_test.sql script.


-- *****************************************************************
-- Notes:
--   Switch to plsql_compiler_flags when using 9i.
-- *****************************************************************

-- ALTER SESSION SET plsql_compiler_flags = 'INTERPRETED';
PROMPT Interpretted
EXEC test_speed;

-- ALTER SESSION SET plsql_compiler_flags = 'NATIVE';
ALTER SESSION SET plsql_code_type = 'NATIVE';
EXEC test_speed;

The output from the script shows that the natively compiled code runs faster.

SQL> @native_comp_test.sql

Session altered.

Procedure altered.


PL/SQL procedure successfully completed.

Elapsed: 00:00:00.74

Session altered.

Procedure altered.


PL/SQL procedure successfully completed.

Elapsed: 00:00:00.66

If we recreate the test_speed procedure using the test_speed_2.sql script we can measure the affect of native compilation of code containing database calls.


  l_date  DATE;
  FOR i IN 1 .. 1000000 LOOP
    INTO   l_date
    FROM   dual;

With the procedure recreated running the native_comp_test.sql again produces the following results.

SQL> @native_comp_test.sql

Session altered.

Procedure altered.


PL/SQL procedure successfully completed.

Elapsed: 00:01:22.03

Session altered.

Procedure altered.


PL/SQL procedure successfully completed.

Elapsed: 00:01:19.32

Once again the natively compiled code is faster, but the differences here are still due to the procedural code, rather than the database calls.

By default all shared libraries are stored in the same directory, which can cause a problem when there are many natively compiled objects.  The point where problems can occur depends on the platform and the source quoting the figure, but the lowest I've read says in excess of 5,000 files can be a problem.

The system level plsql_native_library_subdir_count parameter gets round this issue by telling Oracle to distribute the shared libraries in the specified number of subdirectories.  The directories must be present in the directory pointed to by the plsql_native_library_dir parameter and there names must be in the form "dn", where "n" is the zero-based directory number.  Most articles suggest 1,000 subdirectories is a suitable number to work with, and the following script can be used to generate a directory creation script.

SPOOL mkdir_cmd_file
  FOR i IN 0..999
    DBMS_OUTPUT.put_line('mkdir d' || TO_CHAR(i));

Once the subdirectories are present the parameter can be set to the appropriate number.

ALTER SYSTEM SET plsql_native_library_subdir_count=1000;

It is possible to natively compile the whole database, including the objects owned by the SYS schema, but this should only be done by following the appropriate note from Oracle Technology Network as it can cause problems if done incorrectly.  At the time of writing the method was only described for Oracle 9i in the following document:

In Oracle 10g the compiled shared libraries are now stored in the database and extracted to the file system as necessary.  This means they form part of the normal backup and recovery process, require no manual maintenance and are available in Real Application Cluster (RAC) configurations.  Native compilation of the package specification and body are independent of each other, meaning either one, the other or both can be natively compiled.

In the next section we will look at one way of hiding performance problems from end users by decoupling processes.

Compiling PL/SQL in Oracle 10g and beyond
Mike Ault

As we noted, starting in Oracle 10g, PL/SQL can be compiled to native code. The compiling, along with overall improvements in PL/SQL compilation can mean speeding up PL/SQL execution by up to 60%. On most Oracle systems, the compile process invokes a special makefile utility that accepts the PL/SQL as input and compiles it into native executable C code. As you may know, Oracle is written in C, and this is the native language for Oracle executables.

There is another benefit to compiling PL/SQL. The compiled code that corresponds to the PL/SQL program is mapped to a PGA as opposed to SGA to allow better concurrent access. With native compilation, PL/SQL that does not contain SQL references can be 2-10 times faster.

However, turning on native PL/SQL compilation is not trivial. To turn native compilation on, you need to provide the proper links inside a special file called a makfile. For Oracle 10g on Windows, we see the make file in the c:\oracle\ora90\plsql\demo directory as prcmake.bat. To get an idea of the complexity, here is a listing of the prcmake.bat file:

@echo off

Rem Use this script to create executables for the demo scripts with PL/SQL
Rem blocks embedded in C code. To create all executables, at the prompt

Rem Environment Check:
if (%MSVCDir%) == () goto msvcdir_error

if (%1) == () goto usage
echo This makefile assumes demos are installed as user scott

proc iname=%1.pc sqlcheck=full CHAR_MAP=VARCHAR2, DBMS=V7 ireclen=132 parse=full sqlcheck=SEMANTICS user=scott/tiger

cl -I%ORACLE_HOME%\oci\include -I%MSVCDir%\include -I%MSVCDir%\mfc\include -D_MT -Zi %1.c /link %ORACLE_HOME%\oci\lib\msvc\oci.lib %ORACLE_HOME%\precomp\lib\msvc\orasql9.lib /libpath:%MSVCDir%\lib msvcrt.lib /nod:libcmt

goto end

echo .
echo Environment variable MSVCDIR must be set before running this batch
echo Please run vcvars32.bat from MS Visual Studio directory.
echo .
goto end

echo .
echo usage prcmake filename.pc [i.e. prcmake examp10]
echo .

Here we see that the prcmake accepts the name of the PL/SQL function or procedure as an input argument. As you can see, setting-up these makefiles can be quite complex, and even an experienced Oracle database Administrator can take several days to get the compiler set-up and working.

In any case, once you gat the makefile working, you must issue the following Oracle commands to turn-on native PL/SQL compilation.

connect pubs/pubs as sysdba;

alter system set plsql_compiler_flags=NATIVE;
alter system set plsql_native_library_dir='c:\oracle\ora90\lib';
alter system set plsql_native_make_utility='prcmake';
alter system set

In Oracle 10g, a PL/SQL procedure or function can be compiled as native C code, rather than interpreted as byte code. It is then stored as a shared library in the file system. The process of compiling a PL/SQL function or procedure is very simple:

SQL> alter function pubs.plus_tax compile;

Compilation results in faster execution of PL/SQL programs because of the elimination of the overhead associated with interpreting byte code, and faster control flow in native code than in interpreted code.

For more details, see the "Easy Oracle Series" a set of books especially designed by Oracle experts to get you started fast with Oracle database technology.


Use PL/SQL Native Compilation in 9i
Mike Ault

The native compilation option in Oracle9i allows you to convert internal stored packages and procedures into compiled shared C libraries on the host server. This native compilation can reduce code execution time by up to a factor of four. The packages and procedures are compiled as native C routines and linked into the Oracle code. This new option in Oracle9i is most effective for computational intensive PL/SQL and shouldn't be used for PL/SQL that does a great deal of SQL execution.

To speed up one or more procedures using this technique follow this procedure:
Update the supplied makefile and enter the appropriate paths and other values for your system. The path of this makefile is:


Use the ALTER SYSTEM or alter session command, or update your initialization file, to set the parameter PLSQL_COMPILER_FLAGS to include the value NATIVE. The default setting includes the value INTERPRETED, and you must remove this keyword from the parameter value.

Compile one or more procedures, using one of these methods:

      • Use the ALTER PROCEDURE or ALTER PACKAGE command to recompile the procedure or the entire package.
      • Drop the procedure and create it again.
      • Use CREATE OR REPLACE to recompile the procedure.
      • Run one of the SQL*Plus scripts that sets up a set of Oracle-supplied packages.
      • Create a database using a preconfigured initialization file with PLSQL_COMPILER_FLAGS=NATIVE.
      • During database creation, the UTLIRP script is run to compile all the Oracle-supplied packages.

To be sure that the process worked, you can query the data dictionary to see that a procedure is compiled for native execution. To check whether an existing procedure is compiled for native execution or not, you can query the data dictionary views USER_STORED_SETTINGS, DBA_STORED_SETTINGS, and ALL_STORED_SETTINGS. For example, to check the status of the procedure MY_PROC, you could enter:

SELECT param_value FROM user_stored_settings WHERE
  param_name = 'PLSQL_COMPILER_FLAGS'
  and object_name = 'MY_PROC';

The PARAM_VALUE column has a value of NATIVE for procedures that are compiled for native execution, and INTERPRETED otherwise.

After the procedures are compiled and turned into shared libraries, they are automatically linked into the Oracle process. You do not need to restart the database, or move the shared libraries to a different location. You can call back and forth between stored procedures, whether they are all compiled in the default way (interpreted), all compiled for native execution, or a mixture of both.

Because the PLSQL_COMPILER_FLAGS setting is stored inside the library unit for each procedure, procedures compiled for native execution are compiled the same way when the procedure is recompiled automatically after being invalidated, such as when a table that it depends on is recreated.

You can control the behavior of PL/SQL native compilation through the ALTER SYSTEM or alter session commands or by setting or changing these parameters in the initialization file:

      • PLSQL_NATIVE_LIBRARY_DIR (cannot be set by alter session for security reasons)

An example of compiling a PL/SQL Procedure for Native Execution is shown in Figure 3.

connect scott/tiger;
set serveroutput on;
alter session set plsql_native_library_dir='/home/orauser/lib';
alter session set plsql_native_make_utility='gmake';
alter session set plsql_native_make_file_name='/home/orauser/';
alter session set plsql_compiler_flags='NATIVE';
create or replace procedure hello_native_compilation
  dbms_output.put_line('Hello world');
  select sysdate from dual;

Figure 3: Example use of Native Compilation

As the procedure is compiled, you see the various compilation and link commands being executed. The procedure is immediately available to call, and runs as a shared library directly within the Oracle process.

Limitations of Native Compilation

When a package specification is compiled for native execution, the corresponding body should be compiled using the same settings.
The Oracle provided debugging tools for PL/SQL do not handle procedures compiled for native execution.

When many procedures and packages (typically, over 5000) are compiled for native execution, having a large number of shared objects in a single directory might affect system performance. In this case, you can have the DBA set the initialization parameter PLSQL_NATIVE_LIBRARY_SUBDIR_COUNT in the initialization file before creating the database or compiling the PL/SQL packages or procedures. Set this parameter to a value that makes sense for your environment and operating system, Oracle suggests 1000 but this seems like overkill to me. Once the parameter is set and the DB restarted, create subdirectories underneath the directory specified in the PLSQL_NATIVE_LIBRARY_DIR parameter. The subdirectories must be named d0, d1, d2 ... d999, up to the value specified for the subdirectory count. When the procedures are compiled for native execution, the DLLs will be automatically distributed among these subdirectories by the PL/SQL compiler.


Also see this research on compiling PL/SQL:

If you like Oracle tuning, you may enjoy my new book "Oracle Tuning: The Definitive Reference", over 900 pages of BC's favorite tuning tips & scripts. 

You can buy it direct from the publisher for 30%-off and get instant access to the code depot of Oracle tuning scripts.



Oracle Training at Sea
oracle dba poster

Follow us on Twitter 
Oracle performance tuning software 
Oracle Linux poster


Burleson is the American Team

Note: This Oracle documentation was created as a support and Oracle training reference for use by our DBA performance tuning consulting professionals.  Feel free to ask questions on our Oracle forum.

Verify experience! Anyone considering using the services of an Oracle support expert should independently investigate their credentials and experience, and not rely on advertisements and self-proclaimed expertise. All legitimate Oracle experts publish their Oracle qualifications.

Errata?  Oracle technology is changing and we strive to update our BC Oracle support information.  If you find an error or have a suggestion for improving our content, we would appreciate your feedback.  Just  e-mail:  

and include the URL for the page.


Burleson Consulting

The Oracle of Database Support

Oracle Performance Tuning

Remote DBA Services


Copyright © 1996 -  2020

All rights reserved by Burleson

Oracle ® is the registered trademark of Oracle Corporation.