Home arrow Oracle arrow Tuning PL/SQL Code

Tuning PL/SQL Code

In this conclusion to a nine-part series on managing PL/SQL code, you will learn how to analyze and optimize your code's performance. This article is excerpted from chapter 20 of the book Oracle PL/SQL Programming, Fourth Edition, written by Steven Feuerstein and Bill Pribyl (O'Reilly; ISBN: 0596009771). Copyright © 2006 O'Reilly Media, Inc. All rights reserved. Used with permission from the publisher. Available from booksellers or direct from O'Reilly Media.

  1. Tuning PL/SQL Code
  2. Optimizing PL/SQL Performance
  3. Protecting Stored Code
  4. Dynamic Wrapping with DBMS_DDL
  5. Guidelines for Working with Wrapped Code
By: O'Reilly Media
Rating: starstarstarstarstar / 22
December 20, 2007

print this article



Analyzing Performance of PL/SQL Code

Before you can tune your application, you need to figure out what is running slowly and where you should focus your efforts. Oracle and third-party vendors offer a variety of products to help you do this; generally they focus on analyzing the SQL statements in your code, offering alternative implementations, and so on. These tools are very powerful, yet they can also be very frustrating to PL/SQL developers. They tend to offer an overwhelming amount of performance data without telling you what you really want to know: how fast did a particular program run and how much did the performance improve after making this change?

To answer these questions, Oracle offers a number of built-in utilities. Here are the most useful:


This built-in package allows you to turn on execution profiling in a session. Then, when you run your code, Oracle uses tables to keep track of detailed information about how long each line in your code took to execute. You can then run queries on these tables or—much preferred—use screens in products like Toad or SQL Navigator to present the data in a clear, graphical fashion.


Use this built-in function to calculate the elapsed time of your code down to the hundredth of a second. The scripts tmr.ot and plvtmr.pkg (available on the book’s web site) offer an interface to this function that allows you to use “timers” (based on DBMS_UTILITY.GET_TIME) in your code. These make it possible to time exactly how long a certain operation took to run and even to compare various implementations of the same requirement.

In Oracle Database 10g, you can also call DBMS_UTILITY.GET_CPU_TIME to calculate elapsed CPU time.

In case you do not have access to a tool that offers an interface to DBMS_PROFILER, here are some instructions and examples.

First of all, Oracle does not install DBMS_PROFILER for you automatically. To see if DBMS_PROFILER is installed and available, connect to your schema in SQL*Plus and issue this command:


If you then see the message:

  ORA-04043: object dbms_profiler does not exist

you will have to install the program.

For early Oracle versions, such as Oracle7 and Oracle8 Database, you need to ask your DBA to run the following scripts under a SYSDBA account (the first creates the package specification, the second the package body):



For later versions, you need to run the $ORACLE_HOME/rdbms/admin/profload.sql file instead, also under a SYSDBA account.

You then need to run the $ORACLE_HOME/rdbms/admin/proftab.sql file in your own schema to create three tables populated by DBMS_PROFILER:

Parent table of runs

Program units executed in run

Profiling data for each line in a program unit

Finally, you will probably find it helpful to take advantage of some sample queries and reporting packages offered by Oracle in the following files:



Once all these objects are defined, you gather profiling information for your application by writing code like this:

          'showemps ' ||

Once you have finished running your application code, you can run queries against the data in the PLSQL_PROFILER_ tables. Here is an example of such a query that displays those lines of code that consumed at least 1% of the total time of the run:

  /* File on web: slowest.sql */
                 p1.total_time / 10000000,
|| '-'
           || TO_CHAR (p1.total_occur) AS time_count,
              p2.unit_owner || '.' || p2.unit_name unit,
TO_CHAR (p1.line#)
           || '-'
           || p3.text text
      FROM plsql_profiler_data p1,
           plsql_profiler_units p2,
           all_source p3,
           plsql_profiler_grand_total p4 

     WHERE p2.unit_owner NOT IN ('SYS', 'SYSTEM')
       AND p1.runid = &&firstparm
       AND (p1.total_time >= p4.grand_total / 100)
       AND p1.runid = p2.runid
       AND p2.unit_number = p1.unit_number
       AND p3.owner = p2.unit_owner
       AND p3.line = p1.line#
       AND p3.NAME = p2.unit_name
ORDER BY p1.total_time DESC;

As you can see, these queries are fairly complex (I modified one of the canned queries from Oracle to produce the above four-way join). That’s why it is far better to rely on a graphical interface in a PL/SQL development tool.

After you’ve analyzed your code and identified bottlenecks, the following sections can help you determine what kinds of changes to make to improve code performance.

>>> More Oracle Articles          >>> More By O'Reilly Media

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort


- Oracle Java Security Woes Continue
- Oracle's New IaaS Cloud Option: There's a Ca...
- Oracle Acquires Eloqua to Boost Cloud Presen...
- Choosing Innovation: Oracle Survey Insights
- Oracle Fixes Privilege Escalation Bug
- Oracle`s Communications Service Availability...
- Oracle Releases Exalytics, Taleo Plans
- Oracle Releases Communications Network Integ...
- Oracle Releases Communications Data Model 11...
- Oracle Releases PeopleSoft PeopleTools 8.52
- Oracle Integrates Cloudera Apache Distro, My...
- Oracle Releases MySQL 5.5.18
- Oracle Announces NoSQL Database Availability
- Sorting Database Columns With the SELECT Sta...
- Retrieving Table Data with the LIKE Operator

Developer Shed Affiliates


Dev Shed Tutorial Topics: