Home | Tip of the Week | Tip of the Week Archive | Partners | Clients | History | Friends

Tip of the Week (Archived)
Perception is Reality?
Improving Performance with DBMS_JOB

I really did not have anything I thought was interesting for this week's tip, so I had been avoiding even starting to put something together. But while doing some research on the Internet on regular expressions (yes, I do lead an exciting life), I came across something from Tom Kyte that not only was interesting, but I could apply to a real world problem (and had nothing at all to do with regular expressions).

The Tom Kyte article is available at http://www.oracle.com/technology/oramag/oracle/06-jul/o46asktom.html, and the point he is making is that the perception of performance is frequently as important as performance. If the user has to wait for something to happen, performance is bad. If the user does not have to wait, then performance is good, even if the amount of time the process takes is the same. Tom's example is about executing the command DROP USER username CASCADE. Executing this command interactively could take some time if the user schema contains a large number of objects, and the perception is that performance is bad because the user has to wait. But by using DBMS_JOB to run the same command in the background, control is returned to the user immediately, so performance is good. Take a look at the article for details.

In our case, we developed an application into which data is loaded from text files. The load process is complex, and it is not uncommon for files to contain several hundred thousand records. The application allows the user to enter information about processing the file: format, layout, default values, etc., and to load the data into the database immediately in the foreground, immediately in the background, or to schedule the process to run at a specific time. The user also has the ability to delete the results of a load, if, for example, the layout was defined incorrectly. Since the delete process is relatively simple, the procedure runs interactively and can take several minutes for large amounts of data. Performance is not acceptable.

This was the perfect opportunity to apply this technique. The application provides a way to mark a set of data as "deleted," and the user interface calls a stored procedure to execute the delete of the data. So the user interface required no changes. I split the processing of the current stored procedure into two procedures. The original stored procedure that was deleting the data now marks the data set as deleted and submits the second stored procedure as a job that completes deleting the data. Control is returned immediately to the user, who sees dramatically improved performance.

The original stored procedure, in package pkg_mypkg, was structured like this (code sanitized to protect the innocent).

PROCEDURE p_del_data (
   a_arg1   IN   iINTEGER,
   a_arg2   IN   VARCHAR2
IS
-- Define variables

.

BEGIN
-- Do some validation

.

   UPDATE tab WHERE ...;

   DELETE tab4 WHERE ...;

   DELETE tab3 WHERE ...;

   DELETE tab2 WHERE ...;

   DELETE tabl WHERE ...;

   COMMIT;

EXCEPTION

-- Handle errors

END p_del_data;

The new stored procedures look like this.

PROCEDURE p_del_data (
   a_arg1   IN   iINTEGER,
   a_arg2   IN   VARCHAR2
IS
-- Define variables

   l_job   INTEGER;

.

BEGIN
-- Do some validation

.

   UPDATE tab WHERE ...;

   COMMIT;

   DBMS_JOB.SUBMIT (l_job, 'pkg_mypkg.p_del_data_job (' || a_arg1 || ', ''' || arg2 || ''');');

   COMMIT;

EXCEPTION

-- Handle errors

END p_del_data;

 

PROCEDURE p_del_data_job (
   a_arg1   IN   iINTEGER,
   a_arg2   IN   VARCHAR2
IS
-- Define variables

.

BEGIN
   DELETE tab4 WHERE
...;

   DELETE tab3 WHERE ...;

   DELETE tab2 WHERE ...;

   DELETE tabl WHERE ...;

   COMMIT;

EXCEPTION

-- Handle errors

END p_del_data_job;

All procedures need to be defined in the package header.

The results, as seen through SQL*Plus, are the following. Using the original procedure, the user waited one minute, 40 seconds.

exec pkg_mypkg.p_del_data (1170, 'N')
pkg_mypkg.p_del_data start 28-JUN-2006 15:47:12
pkg_mypkg.p_del_data end 28-JUN-2006 15:48:52

Using the new procedure, the user waited just one second.

exec pkg_mypkg.p_del_data (1171, 'N')
pkg_mypkg.p_del_data start 28-JUN-2006 15:52:31
pkg_mypkg.p_del_data end 28-JUN-2006 15:52:32

Perception is reality.

Note: This tip was tested on Oracle9i.

Was this tip useful? Did you find any errors? Do you have any suggestions? Do you care? Click here for the tip feedback page. Thank you.

2000 Turnberry Circle, Glenmoore, PA 19343
Voice: (610) 942-1979
Fax: (610) 942-1990
Email


© 2006 Alydan Consulting, Inc.