techniques tuning plsql apps twp

download techniques tuning plsql apps twp

of 26

Transcript of techniques tuning plsql apps twp

  • 8/14/2019 techniques tuning plsql apps twp

    1/26

    Techniques For Tuning PL/SQL

    Applications

    An Oracle Technical White Paper

    M arch 199 9

  • 8/14/2019 techniques tuning plsql apps twp

    2/26

    Techniques For Tuning PL/ SQL Applications

    March 1999

    2

    INTRODUCTION

    Oracle8i PL/SQL

    provides seamless and tight integration with SQL and the Oracle server. Oracle

    PL/SQL is widely used for building scalable, portable, and robust enterprise applications. As

    organizations grow, there is a need to make the applications that service them more scalable and

    faster. Moreover, due to the explosive growth of the amount of available data, performance has now

    become a critical issue, even for customers who have not modified their existing applications.

    Oracle8i PL/SQL has several new features that improve application performance and increase

    scalability, by optimizing memory usage. Some of these features are transparent to the end user and,

    with simple recompilation, will improve the performance of existing applications. Other features

    require the use of new syntax and, therefore, the modification of existing applications, to exploit the

    benefits that the new features offer.

    To improve application performance and scalability, the following sequence of steps needs

    to be executed:

    = Evaluate performance of existing applications, and identify bottlenecks/areas for improvement.= Analyze the characteristics of the application code that needs improvement, and identify the

    relevant features that can be used for improving performance.

    =Develop/modify the application so that they can use features and performance tips to extract themaximum performance.

    This paper describes the PL/SQL tools and features for implementing the above methodology, in the

    following order:

    = A discussion of the use of profiling tools for benchmarking existing applications and identifyingareas for improving performance.

    = A descript ion of the features that can significantly improve performance. In addition toperformance improvements, this paper also discusses the memory usage improvements of PL/SQL

    programs. Significant improvements have been made to reduce the session memory (also called,

    UGA user global memory) that PL/SQL requires, resulting in better PL/SQLapplication scalability.

    = Some PL/SQL performance tips that can be used for improving application performanceand scalability.

  • 8/14/2019 techniques tuning plsql apps twp

    3/26

    Techniques For Tuning PL/ SQL Applications

    March 1999

    3

    APPLICATION A NA LYSIS

    As mentioned in the introduction, the first step in improving an application's performance is to

    identify the characteristics of the application and the bottlenecks in the code. This will allow the

    developer to determine the portions of the application where the maximum time is spent, which, in

    turn, allows att ention to be focused on the relevant program segments and data structures. The

    Profiling tool described below can be used to analyze PL/SQL applications.

    PROFILING

    As Oracle8i PL/SQL users develop increasingly large numbers of PL/SQL packages that are used as

    components, the need to ident ify and isolate performance problems becomes critical. Oracle8i

    provides a profiler, with which customers can:

    = Profile their existing PL/SQL applications.= Locate bottlenecks.= Focus on improving the performance of any bottlenecks found.

    Using the profiling tool, application developers can generate profiling information for all named

    library units used in a single session. The profiling information is stored in a database, to help

    generate information on time spent in each PL/SQL line, module, and routine. A sample textual

    report writer is provided (refer to [7] for more details). The report writer can extract the persistent

    profiling information that the profiler stores, to identify the time spent at each line. Thus, it allows

    application developers to identify the program segments that need improvement.

    Once the program segments that require improvements have been identified, the next step is to

    analyze why time is spent in certain code segments. The feedback from the profiler can be used to re-

    work the algorithms (or perhaps select new algorithms) used in the application. In addition, the

    analysis phase can point out inefficiencies caused by the choice of inappropriate data structures. This

    information must be considered together with the new features that PL/SQL provides, to identify

    whether more performance can be extracted from the applications. To conclude, application analysis

    is an important phase that drives the rest of the application tuning effort that developers undertake.

  • 8/14/2019 techniques tuning plsql apps twp

    4/26

    Techniques For Tuning PL/ SQL Applications

    March 1999

    4

    PL/SQL FEATURES FOR IM PROVING PERFORMAN CE

    Oracle8 PL/SQL Release 8.0 and Oracle8i PL/SQL Release 8.1 support a variety of new features that

    can be used to develop more efficient applications. The following sections describe the new features

    that have been added to the language. In addition, Oracle devoted a lot of effort towards

    transparently improving the performance of the existing Oracle PL/SQL applications.

    NEW FEATURES IN ORACLE8 IPL/SQL

    As summarized in the table below, several new capabilities have been added in Oracle8i PL/SQL in

    the areas of performance.

    PROGRAM

    CHARACTERISTICS

    IMPROVEMENT FEATURE

    Applications that execute SQL

    statements in a loop

    Faster data transfer between

    PL/SQL and SQL

    Bulk Binds

    Applications that contain

    functions/procedures that pass

    large records, ADTs, or

    collections as parameters

    Faster parameter passing mode NOCOPY

    Applications that use the

    DBMS_SQL package

    Faster support for dynamic SQL

    statements

    Native dynamic SQL

    Applications that implement

    computational business logic

    with few database (SQL)

    operations

    Efficient and convenient

    alternative to implement

    compute-intensive code

    External Procedures

    The following sections describe these features in more detail.

  • 8/14/2019 techniques tuning plsql apps twp

    5/26

    Techniques For Tuning PL/ SQL Applications

    March 1999

    5

    Bulk Binds: Faster Data Transfer Betw een PL/SQL and SQL

    The PL/SQL interpreter executes all the procedural statements, but sends the SQL statements to the

    SQL engine, which parses and executes the SQL statements and, in some cases, returns data to the

    PL/SQL engine. Although this execution path has been heavily optimized, to support faster

    execution of the embedded SQL statements, the context switch adds some overhead. The

    performance penalty can become noticeable when SQL statements are nested in loops, as

    demonstrated in the following example:

    -- Assume that orderId, orderDate, etc. (one for each column

    of the

    -- table Orders) have been filled appropriately with all thenew

    -- Orders that need to be inserted into the database. Assume

    that

    -- there are 1000 orders.

    FOR i In 1..1000

    LOOP

    INSERT INTO Orders VALUES (orderId(i), orderDate(i), ...);

    END LOOP;

    The overhead can be reduced, by minimizing the number of context switches. The bulk binds

    features allow users to decrease the overhead, by operating on multiple rows in a single DML

    statement. With bulk binds, entire collections, not just the individual collection elements, are

    passed back and forth between PL/SQL and SQL engines. Oracle8i PL/SQL supports new

    keywords FORALL and BULK COLLECT to support bulk binds. The above example may be

    transformed as follows, to use bulk binds:

  • 8/14/2019 techniques tuning plsql apps twp

    6/26

    Techniques For Tuning PL/ SQL Applications

    March 1999

    6

    FORALL i In 1..1000

    INSERT INTO Orders VALUES (orderId(i), orderDate(i), ...);

    For more details regarding this feature, please refer to [2].

    NOCOPY: Faster Parameter Passing

    PL/SQL supports three parameter passing modes:

    = IN parameters are passed by reference.= IN OUT parameters are implemented as copy-in/copy-out.= OUT parameters are implemented as copy-out.

    This copying protects the original values of the arguments, if exceptions are raised in the called

    function/procedure. However, such copying imposes CPU and memory overhead, especially when

    the parameters involved are large data structures, such as large strings or collections.

    In Oracle8i, PL/SQL supports a new "NOCOPY" modifier that can be used to avoid this overhead, by

    allowing IN OUT and OUT parameters to be passed efficiently by reference, when possible. Use of

    this new modifier will result in performance improvements for any application that passes large data

    structures as IN OUT or OUT parameters. The following example shows the use of the

    NOCOPY modifier.

    -- The IN OUT parameter "word_list" in "add_entry" is passed

    by

    -- reference when possible

    TYPE Definition IS RECORD (

    word VARCHAR2(20),

    meaning VARCHAR(200)

  • 8/14/2019 techniques tuning plsql apps twp

    7/26

  • 8/14/2019 techniques tuning plsql apps twp

    8/26

    Techniques For Tuning PL/ SQL Applications

    March 1999

    8

    DBMS_SQL package. In addition, the DBMS_SQL approach is based on a procedural API and, as a

    result, suffers from high procedure call and data copy overhead. We have seen significant

    performance improvements (up to 200%) over DBMS_SQL in our small benchmarks.

    For example, consider the following program segment that demonstrates the use of DBMS_SQL. It

    also illustrates the use of native dynamic SQL. Please refer to [3] for more details.

    DML example, using the

    DBMS_SQL package

    Equivalent DML example with

    Native Dynamic SQL

    PROCEDURE insert_into_table

    (table_name VARCHAR2,

    deptnumber NUMBER,

    deptname VARCHAR2,

    location VARCHAR2)

    IS

    cur_hdl INTEGER;

    stmt_str

    VARCHAR2(200);

    rows_processed

    BINARY_INTEGER;

    BEGIN

    stmt_str := 'insert into

    ' || table_name || ' values

    (:deptno,

    :dname, :loc)';

    -- open cursor

    cur_hdl :=

    dbms_sql.open_cursor;

    PROCEDURE insert_into_table

    (table_name VARCHAR2,

    deptnumber NUMBER,

    deptname VARCHAR2,

    location VARCHAR2)

    IS

    stmt_str VARCHAR2(200);

    BEGIN

    stmt_str := 'insert into '

    || table_name || ' values

    (:deptno,

    :dname,

    :loc)';

    -- bundled execution using

    native dynamic SQL

    EXECUTE IMMEDIATE stmt_str

    USING

    deptnumber, deptname,

    location;

    END insert_into_table;

  • 8/14/2019 techniques tuning plsql apps twp

    9/26

    Techniques For Tuning PL/ SQL Applications

    March 1999

    9

    -- parse cursor

    dbms_sql.parse(cur_hdl,

    stmt_str, dbms_sql.native);

    -- supply binds

    dbms_sql.bind_variable(cur_hd

    l, ':deptno', deptnumber);

    dbms_sql.bind_variable(cur_hd

    l, ':dname', deptname);

    dbms_sql.bind_variable(cur_hd

    l, ':loc', location);

    -- execute cursor

    rows_processed :=

    dbms_sql.execute(cur_hdl);

    -- close cursor

    dbms_sql.close_cursor(cur_hdl

    );

    END insert_into_table;

    On every bind, the DBMS_SQL package implementation makes copies of the PL/SQL bind variable

    into its space, for use during the execution phase. Similarly, on every fetch, the data is first copied

    into the space that the DBMS_SQL package manages. Therefore, the fetched data is copied, one

    column at a time, into the appropriate PL/SQL variables, resulting in a significant data

    copying overhead.

  • 8/14/2019 techniques tuning plsql apps twp

    10/26

    Techniques For Tuning PL/ SQL Applications

    March 1999

    10

    External Procedures: Faster Execution of Compute-Intensive Logic

    Oracle8 PL/SQL Release 8.0 provided support for external procedures, which allow a simple, easy,

    and safe way to interface external systems and 3GL application code with the database server, while

    preserving transactional semantics. They can be called from a number of different contexts,

    including from SQL, PL/SQL stored procedures, functions and triggers, client OCI, and

    Precompiler programs.

    Several optimizations were done in Oracle8i PL/SQL Release 8.1 that decrease the overhead

    associated with callouts. Customers migrating from Oracle8 to Oracle8i can take advantage of the

    performance benefit, by merely recompiling their applications.

    PL/SQL is closely tied to the Oracle Server, for SQL transaction processing. Complex number

    crunching can be very expensive in PL/SQL and is best done efficiently, in lower level languages like

    C. Consider the following CPU-int ensive PL/SQL code fragment for computing the

    Fibonacci numbers:

    CREATE FUNCTION fib(n PLS_INTEGER) RETURN PLS_INTEGER IS

    BEGIN

    IF (n < 2)

    RETURN n;

    ELSE

    RETURN (fib(n-2) + fib(n-1));

    END IF;

    END;

    And the C fragment:

  • 8/14/2019 techniques tuning plsql apps twp

    11/26

    Techniques For Tuning PL/ SQL Applications

    March 1999

    11

    unsigned int fib(n)

    unsigned int n;

    {

    if (n < 2)

    return n;

    else

    return (fib(n-2) + fib(n-1));

    }

    Our experiments have shown that C code performs better than PL/SQL, even for values as

    small as N=10.

    TRANSPARENT PL/SQL PERFORMANCE IMPROVEMENTS

    The Oracle8i PL/SQL Release 8.1 runtime engine has been further tuned to allow existing

    applications to run faster transparently. The following table highlights these as well as

    improvements made in Oracle8 PL/SQL Release 8.0:

  • 8/14/2019 techniques tuning plsql apps twp

    12/26

    Techniques For Tuning PL/ SQL Applications

    March 1999

    12

    Program Characteristics Feature Release

    Applications that use the standard builtins

    provided by PL/SQL

    Optimization of Package STANDARD

    Builtins

    8.1

    OCI, SQL*Plus, DBMS_SQL, etc.

    applications that invoke PL/SQL stored

    procedures, by building anonymous blocks

    Faster Anonymous Block Execution 8.1

    Applications that make RPC calls (client-

    to-server or server-to-server) and pass large

    records, ADTs, and collections

    RPC Parameter Passing Improvements 8.1

    Application uses triggers, and calls PL/SQL

    functions from SQL context

    Faster Calling PL/SQL from SQL Context 8.0

    All applications Code-generation optimizations to minimize

    temporaries

    8.0

    Applicat ions that use records Efficient Implementat ion of PL/SQL

    Records

    8.0

    Applications that use collections Improved PL/SQL Index-By Table

    Implementation

    8.0

    Optimization of Package STANDARD Built-Ins

    Calls to package Standard built-ins (for example, TO_CHAR, TO_DATE, SUBSTR, etc.) were

    improved in Oracle8i PL/SQL, by optimizing the code path to call such built-ins, resulting in faster

    execution. This is a huge transparent improvement, because most applications are heavy users of

    these built-ins. Our benchmark runs have shown performance gains of 10-30%. The performance

    gains become more significant if built-ins are used more heavily in the application.

  • 8/14/2019 techniques tuning plsql apps twp

    13/26

    Techniques For Tuning PL/ SQL Applications

    March 1999

    13

    Faster Anonymous Block Execution

    The following improvements were made in Oracle8 i PL/SQL Release 8.1:

    =The invocation of anonymous blocks with bind variables has doubled in speed, due to elimination ofconsiderable code path in bind variable processing.

    = Accessing elements of host array bind variables is significantly faster in Oracle8i PL/SQL.= We now optimize host binds that are used only in SQL statements, in anonymous PL/SQL blocks,

    by avoiding unnecessary temporaries.

    = Redundant rebinds for host bind variables to SQL statements in an anonymous block have beeneliminated for repeated executions of the anonymous block.

    In addition, and perhaps more significantly, calling PL/SQL functions and triggers from SQL will

    now be much faster, because this is internally implemented, using anonymous blocks with

    bind variables.

    RPC Parameter Passing Improvement

    The overhead associated with RPC parameters has been reduced in Oracle8i PL/SQL Release 8.1, by

    eliminating some redundant temporaries. Any call that passes large records, ADTs, or collections

    (including index-by tables) will benefit from this optimization. This optimization is applicable to

    the server-to-server, as well as client-server RPC calls.

    Faster Calling PL/ SQL From SQL Context

    The overhead of calling PL/SQL functions (or triggers) from SQL context has been made negligible in

    Oracle8 PL/SQL Release 8.0. Several optimizations were done in this area. Anonymous blocks built

    for invoking PL/SQL from SQL are now compiled and kept as part of the parent SQL cursor. A

    critical latching bottleneck, which made PL/SQL invocation in Parallel Query operations very

    expensive, has been eliminated. Some structures (for example, date context) are now cached in the

    PL/SQL interpreter context. As a result, repeated invocations of PL/SQL (for example, on every row

    of a SQL query) have been made more efficient. Invocation of anonymous blocks with bind variables

    is much faster (as described in the previous section).

  • 8/14/2019 techniques tuning plsql apps twp

    14/26

    Techniques For Tuning PL/ SQL Applications

    March 1999

    14

    Code Generation of Optimizations to Minimize Use of Temporaries (Oracle8Improvement)

    Code generation optimizations were done to minimize the use of temporaries during expression

    evaluation, thereby resulting in smaller and more efficient MCODE. For example, consider the

    following PL/SQL statement:

    str1 := str2 || str3;

    In PL/SQL Releases 2.x, the result of the expression, "str2 || str3," would be computed into a

    temporary variable, and then the temporary would be copied to the variable "str1," with appropriate

    constraint checking. From PL/SQL Release 8.0 on, a single byte-code instruction is generated to

    compute and store the result of the concatenation directly into "str1."

    This significantly improves execution time, by reducing the amount of data copy and the time spent

    in creation of temporaries. This temporary elimination optimization also applies to assignment

    statements involving implicit conversions, such as:

    number_variable := pls_integer_variable;

    number_variable := char_variable;

    For the above statements, temporaries are no longer generated to hold the result of the type

    conversion. The left-hand side variable is directly used as the target of the conversion.

    Efficient Implementation of PL/ SQL Records

    In PL/SQL Release 2.3.4 and earlier releases, there was no true support for RECORDs in the run-

    time. The compiler exploded a RECORD into its individual scalar fields, which resulted in

    inefficient code. Starting with Release 8.0, the PL/SQL run-time provides native support for

    composite types, such as RECORDs and OBJECTs. The run-time uses structural type descriptors,

    generated during compilation, to implement operations (such as "copy," "RPC argument

    marshaling,", etc.) on data items of these types.

  • 8/14/2019 techniques tuning plsql apps twp

    15/26

    Techniques For Tuning PL/ SQL Applications

    March 1999

    15

    Improved PL/ SQL Index-By Table Implementation

    Collection data types (index-by tables, nested tables, and varrays) have been implemented using a

    new paged-array representation. This replaces the previous B-tree-based implementation for index-

    by tables, which had the disadvantage that there could be a lot of data movement during insert

    operations, due to tree balancing.

    Operations such as lookup, insert, and copy should be faster now. For dense collections, especially,

    the paged-array scheme exhibits much better memory utilization characteristics than the previous B-

    tree scheme.

    Other Enhancements

    A number of other enhancements have been added that make PL/SQL execution efficient. This list

    includes faster implementations for:

    = Byte-code operand fetches.= Scope (procedure frame) entry and exit (by speeding up interpreter's register save/restore operations).= Common built-in operations, like "to_char" on numeric types.= Access to a package's own global variables.= Bind variable reads/writes.= Dynamic SQL that uses DBMS_SQL.= Assignments to numbers without scale and precision constraints.= Null initialization of frame variables on entry to scope.= Runtime code used for executing the RETURNING INTO clause of SQL DML statements was

    tuned to reduce overhead.

    TRANSPARENT M EMORY USAGE IMPROVEMENTS

    The scalability of large applications directly depends on the memory requirement of the application

    code. In addition to the performance improvements, the memory management in Oracle8 has been

    tuned to reduce the memory usage of the applications. The size of PL/SQL MCODE (compiled byte-

  • 8/14/2019 techniques tuning plsql apps twp

    16/26

    Techniques For Tuning PL/ SQL Applications

    March 1999

    16

    code form), which is loaded in system global memory (SGA), is down about 20-25%, compared to

    Oracle7. Major improvements have been made in reducing user global memory (UGA) that PL/SQL

    packages performing SQL operations consume.

    For applications such as Oracle Office, the UGA consumption due to PL/SQL packages is down about

    40%. These improvements have played a crucial role in enabling Oracle8 applications to scale to

    tens of thousands of users (see [1]). The key improvements are summarized in the table below:

    Program Characterist ics Feature Release

    All applications Reduction in Shared Pool (SGA)

    fragmentation

    2.3, 8.0

    All applications Reduction in SGA utilization 8.0

    Applications with SQL statements Reduction in UGA, due to

    Improvements in Embedded SQL

    Execution

    8.0

    Applications that have variables of

    VARCHAR2 and RAW datatypes

    Dynamic Allocation of Large

    VARCHAR2 and RAW variables

    8.0

    Applications that dont need to maintainstate across calls to the server

    Serially Reusable Packages 8.0

    The following sections describe these improvements in more detail.

    Reduction in Shared Pool (SGA) Fragmentation

    On the server, the SGA is implemented using shared memory a range of virtual addresses is

    mapped to the shared segment on every Oracle process. As an Oracle instance continues to servicerequests, the free SGA memory tends to become fragmented, thus making it harder to satisfy

    requests for large chunks.

    Execution of a PL/SQL library unit involves loading it s MCODE into SGA memory. Two major sub-

    pieces of the MCODE are the code segment and constant pool. The code segment contains the

  • 8/14/2019 techniques tuning plsql apps twp

    17/26

    Techniques For Tuning PL/ SQL Applications

    March 1999

    17

    byte-code (or the instruction) sequence for the program. The constant pool piece holds the literal

    constants in the program, as well as various other descriptors that the interpreter uses to perform

    tasks, like PL/SQL RPC, exception processing, SQL processing, and so on.

    Until PL/SQL V2.2, the code segment and the constant pool pieces were allocated as contiguous

    chunks in the SGA. In PL/SQL V2.3, code segment paging was implemented, which helped alleviate

    some of the SGA fragmentation concerns. In PL/SQL V8, the constant pool portion of the PL/SQL

    MCODE is also paged.

    Virtual machines that implement paging completely at load time suffer from the problem that

    instructions or literal data can span page boundaries, and, hence, such VMs need to check for page

    faults during instruction or literal data fetches. This can result in poor performance. In contrast, one

    of the salient characteristics of PL/SQL paging is that parts of the paging logic have been designed

    right into the compiler, which guarantees that no instruction or literal data item will span page

    boundaries. This characteristic helps minimize the number of page table lookups, and also

    eliminates the need to do any segmented fetches at run-time.

    Reduction in SGA Utilization

    The SGA memory consumpt ion of PL/SQL libraries has been considerably reduced. The MCODE

    size of a PL/SQL library unit in V8 is about 20-25% less than in V7. Some of the optimizations doneto achieve this were:

    = The use of a compression scheme in the byte-code operand specification.= Initialization of variables upon entry into a scope that uses a compact descriptor, which lives in the

    constant pool part of the MCODE, instead of using individual byte-code instructions.

    Reduction in UGA Due to Improvements in Embedded SQL Execution

    In V8 there has been a substantial improvement in the execution model for SQL statements

    embedded in PL/SQL, which resulted in substantial UGA memory savings and performance

    improvements. The UGA memory consumption of PL/SQL packages is down about 40% compared

    to Oracle7, due to these changes. Previously, for SQL executed from PL/SQL, a contiguous buffer

    would be allocated in UGA to hold the values of the input and output variables for the SQL

  • 8/14/2019 techniques tuning plsql apps twp

    18/26

    Techniques For Tuning PL/ SQL Applications

    March 1999

    18

    statement. An extra copy step was needed to move data between this buffer and the actual PL/SQL

    variables in the SQL statement. Although this buffer would be reused if the SQL statement was to be

    executed again, the main disadvantage is that it remains allocated in the UGA till the end

    of the session.

    In V8, these input/output buffers have been eliminated. Instead, the binds and defines to the SQL

    statement are done directly, using the PL/SQL variables, thus saving both time spent on the extra

    copy step and UGA memory.

    Dynamic Allocation of Large VARCHAR2 and RAW Variables

    In Oracle8 PL/SQL, variables of type VARCHAR2 and RAW are dynamically allocated and resized

    as appropriate. They are no longer pre-allocated on the PL/SQL execution stack to their maximum

    declared size. This should greatly reduce the memory utilization for applications that pessimistically

    declare large VARCHAR2s/RAWs, but often end up storing only small amounts of data in them.

    Observe that, for package global VARCHAR2 and RAW variables, this implies savings in UGA

    memory. As an optimization, since heap allocated items tend to have a slight performance overhead,

    small VARCHAR2s and RAWs are pre-allocated on the PL/SQL execution stack (like in V7).

    Serially Reusable Packages

    Before Oracle8 PL/SQL, the UGA memory of a package simply stayed around until the end of the

    session, whether or not the application needed it anymore. This limits scalability, since such

    memory grows linearly with the number of users.

    To help applications better manage memory usage, PL/SQL provides the pragma

    SERIALLY_REUSABLE, which lets users mark some packages as "serially reusable." You can so

    mark a package if its state is needed only for the duration of a call to the server (for example, an OCI

    call to the server, a PL/SQL client-to-server or server-to-server RPC).

    The global memory for such packages is not kept in the UGA per user, but instead in a small SGA

    pool. At the end of the call to the server this memory is returned to the pool for reuse. Before reuse,

    the package global variables are initialized to NULL, or to the default values provided.

  • 8/14/2019 techniques tuning plsql apps twp

    19/26

    Techniques For Tuning PL/ SQL Applications

    March 1999

    19

    The pool is kept in SGA memory, so that the work area of a package can be reused across users who

    have requests for the same package. In this scheme, the maximum number of work areas needed for a

    package is only as many as there are concurrent users of the package, which is typically much fewer

    than the total number of logged on users. The use of "serially reusable" packages does increase the

    shared-pool requirements slightly, but this is more than offset by the decrease in the per-user UGA.

    Further, Oracle ages out work areas not in use, when it needs to reclaim shared pool memory.

    PL/SQL PERFORMANCE TIPS

    As mentioned in the introduction, three steps are required to improve application performance and

    scalability. First, analyze the performance of the application, to identify the areas for improvement.

    Second, determine the relevant features that can be used to improve the performance. Finally,

    develop/modify the application, so that it can use features that extract maximum performance.

    This section provides some PL/SQL performance tips for writ ing efficient PL/SQL code. These tips

    can be used to improve the performance of PL/SQL applications.

    VARRAYs vs. Nested Tables

    Oracle8 offers two new collection types: nested tables and varrays. An important difference is that

    varrays have a maximum declared size, whereas nested tables are unbounded. As a result, in Oracle,

    varray data is stored in-line (in the same tablespace), but nested table data is stored out-of-line in a

    separate table. This implies that storing/retrieving varrays typically involves fewer disk accesses.

    Hence, they are more efficient than nested tables. Our experiments indicate that the varrays are 5-

    10% faster than nested tables. However, the difference should increase as the varrays are

    optimized further.

    Nested Tables vs. Index-By Tables

    Nested tables require explicit initialization, while index-by tables are automatically init ialized. In

    addition, nested tables need to be explicitly extended, while index-by tables are automatically

    extended when a larger subscript is encountered. As a result, nested tables are densely allocated,

    while index-by tables are not. Due to these reasons, nested tables are more efficient than index-by

  • 8/14/2019 techniques tuning plsql apps twp

    20/26

    Techniques For Tuning PL/ SQL Applications

    March 1999

    20

    tables. A nested table can replace a dense index-by table, to extract performance benefits in the range

    of 10-30% for tables with 100 to 1000 scalar elements.

    Integer Operations in PL/SQL

    PL/SQL supports PLS_INTEGER as a native datatype: the operations on PLS_INTEGER are

    performed by the PL/SQL interpreter itself. Numeric types, such as INTEGER and NUMBER, are

    represented in the 22 byte Oracle number format. Oracle number libraries are used to implement

    arithmetic operations on these types. Furthermore, the INTEGER type is a constrained subtype of

    NUMBER with a precision of 0. On assignments to INTEGER variables, precision checking is done

    at run-time.

    Both PLS_INTEGER and BINARY_INTEGER are both represented as a signed 4-byte quantity

    ("sb4"). But, BINARY_INTEGER arithmetic is costly: the operands are first converted to Oracle

    number and then the Oracle number library is used to compute the result as another Oracle number.

    This results in increased use of temporaries and data conversion, and, hence, poor performance. On

    the other hand, native integer arithmetic is used to efficiently implement arithmetic operations on

    PLS_INTEGERs.

    The numeric types NATURAL, NATURALN, POSITIVE, POSITIVEN, and SIGNTYPE are

    subtypes of BINARY_INTEGER (refer to [5] for details) with "stricter" range constraints. There isconsiderable overhead (about 3-4 byte-code instructions) in the enforcement of these range

    constraints on every assignment (or parameter passing) to variables of these types.

    Record of Tables vs. Table of Records

    A collection of a related set of values can be stored either as record of tables or table of records. Since

    the record of tables requires maintaining tables of scalars, the elements are stored in-line. However,

    elements are stored out-of-line for table of records. The table below shows a code fragment that

    demonstrates the benefit of using a record of tables.

  • 8/14/2019 techniques tuning plsql apps twp

    21/26

    Techniques For Tuning PL/ SQL Applications

    March 1999

    21

    Table of Records Record of Tables

    DECLARE

    ...

    T Y PE ae_li ne_rec_type IS REC ORD

    (

    source_id N UM BER ,

    source_table VA RCH A R2 (30 ),

    account N UM BER ,

    entered_dr NUMBER,

    entered_cr N UM BER ,

    accounted_dr N UM BER ,

    accounted_cr NU M BER ,

    currency_code VA RCH A R2 (3 0),

    exchange_rate_type VA RCH A R2 (30 ),

    exchange_rate N U M BER ,

    exchange_date DA T E,

    description VARCHAR2(240),

    third_party_id NUMBER,

    third_party_site_id NU M BER

    );T Y PE tbl_type IS T A BL E of rec_type;

    ...

    BEGIN

    ...

    EN D;

    DECLARE

    ....

    T Y PE num_arr IS TA BL E OF number;

    T Y PE char30_arr IS T A BL E OF varchar2(30) ;

    TY PE char240_ arr IS TA BLE OF varchar2(240 );

    T Y PE date_arr IS TA BL E OF date;

    T Y PE rec_type IS RECORD

    (

    source_id num_arr,

    source_table char30_arr,

    account num_arr,

    entered_dr num_arr,

    entered_cr num_arr,

    accounted_dr num_arr,

    accounted_cr num_arr,

    currency_code char30_arr,

    exchange_rate_type char30_arr,

    exchange_rate num_arr,

    exchange_date date_arr,description char240_arr,

    third_party_id num_arr,

    third_party_site_id num_arr

    );

    BEGIN

    ...

    EN D;

    Benchmark results indicate that the record of tables is an order of magnitude faster than the table of

    records, for records/tables with 10,000 elements.

    Constrained Datatypes

    Using NOT NULL constraint s in PL/SQL incurs performance penalty. Consider the

    following program:

    PROCEDURE proc IS

    m NUMBER NOT NULL;

    a NUMBER;

    b NUMBER;

  • 8/14/2019 techniques tuning plsql apps twp

    22/26

    Techniques For Tuning PL/ SQL Applications

    March 1999

    22

    BEGIN

    m : = a + b ;

    m := m * 1.2;

    m : = m * m ;

    ...

    END;

    Since "m" is a NOT NULL constrained number, the result of the expression "a+b" is first computed

    into a temporary, and the temporary is then tested, to ensure it is not NULL. If the temporary is

    NULL an exception is raised, otherwise the value of the temporary is moved to "m." On the other

    hand, if "m" was not constrained, then the result of the expression "a+b" could directly be computed

    into "m." So, a more efficient way to rewrite the above fragment with reduced use of temporaries is:

    PROCEDURE proc IS

    m NUMBER; -- Note: m doesn't have NOT NULL constraint

    a NUMBER;

    b NUMBER;

    BEGIN

    m : = a + b ;

    m := m * 1.2;

  • 8/14/2019 techniques tuning plsql apps twp

    23/26

    Techniques For Tuning PL/ SQL Applications

    March 1999

    23

    m : = m * m ;

    -- enforce constraint programmatically

    IF (m IS NULL) THEN

    -- raise appropriate error

    END IF;

    ...

    END;

    Another thing to note is that the types NATURALN and POSTIVEN are defined to be NOT NULL

    subtypes of NATURAL and POSITIVE, respectively. Hence, users will incur the performance

    penalty described above when using them. Similarly, assignment among the datatypes with different

    range constraints (for example, POSITIVE and BINARY_INTEGER) also incur constraint

    checking overhead.

    Avoid Type Conversions

    PL/SQL does implicit conversions between structurally different types at run-time. Currently, this is

    true even when the source item is a literal constant . A common case where implicit conversions

    result in a performance penalty, but can be avoided, is with numeric types. For instance, assigning a

    PLS_INTEGER variable to a NUMBER variable, or vice versa, will result in a conversion, since their

    representations are different. Such implicit conversions can happen during parameter passing as well.

  • 8/14/2019 techniques tuning plsql apps twp

    24/26

    Techniques For Tuning PL/ SQL Applications

    March 1999

    24

    Some examples of inefficient code and suggestions to fix them are given below:

    = Prevent conversions between numeric types. For example:number_variable := number_variable + 1;

    The literal constant 1 is represented as a native integer. It gets converted to the Oracle NUMBER

    format before the addit ion. Instead, use:

    number_variable := number_variable + 1.0;

    The above is more efficient, because literal floats (like 1.0) are represented as Oracle number, so no

    type conversion happens at run-time. Or better still, when dealing with integer data, use:

    pls_integer_variable := pls_integer_variable + 1;

    = Prevent numeric to character type conversion. For example,char_variable := 10;

    The literal 10 is converted to CHAR at run-t ime, and then copied. Instead, use:

    char_variable := '10';

    CONCLUSIONS

    PL/SQL is a customer-centric language Oracle maintains the language specifications and provides

    the required execution environment. Oracle intends to continue working with the large PL/SQL

    customer base to evolve and enhance the language and execution environment to match user

    requirements. Oracle intends to aggressively improve performance, by working on the

    following projects:

    = Oracle is considering compilation of PL/SQL to C, which will transparently improve theperformance of all PL/SQL applications by native compilation and avoidance of interpreter overhead.

    = Oracle plans to significantly optimize the runtime engine, to allow applications to be automaticallyself tuned, as well as to investigate performance hints at compile time that will help customers

    manually tune their applications.

    = Oracle also plans to enhance the profiler, so that customers can find bottlenecks more easily.

  • 8/14/2019 techniques tuning plsql apps twp

    25/26

    Techniques For Tuning PL/ SQL Applications

    March 1999

    25

    ACKNOWLEDGEMENTS

    The authors of this paper, Ajay Sethi (Editor), Kannan Muthukkaruppan, Chris Racicot, Ashok

    Swaminathan, Ron Decker, Radhakrishna Hari, Chandrasekharan Iyer, Sanjay Krishnamurthy, Neil

    Le, Shirish Puranik, Ian Stocks and Murali Vemulapati thank the PL/SQL Product Development

    team for reviewing the paper. In particular, the authors thank Chandrasekharan Iyer, Thomas

    Kurian, Kannan Muthukkaruppan, Shirish Puranik and Ashok Swaminathan for reviewing the paper

    and for their useful suggestions for improving the paper.

    REFERENCES

    1. Scaling to Thousands of Users with Oracle8, Amit Jasuja and William Maimone, European Oracle

    User's Conference, Vienna, 1997.

    2. Bulk Binds: Faster SQL Execution in PL/SQL, Sanjay Krishnamurthy, Ajay Sethi, and Ashok

    Swaminathan, Oracle8i PL/SQL Whitepaper, 1998.

    3. Native Dynamic SQL in PL/SQL, Kannan Muthukkaruppan, Neil Le, and Ashok Swaminathan,

    Oracle8i PL/SQL Whitepaper, 1998.

    4. NOCOPY: Faster Parameter Passing in PL/SQL, Ajay Sethi and Chandrasekharan Iyer, Oracle8i

    PL/SQL Whitepaper, 1998.

    5. PL/SQL User's Guide and Reference, Oracle8i, 1998.

    6. Improving Performance of PL/SQL Applications - Advances in Oracle8, Kannan Muthukkaruppan,

    Oracle Open World '97.

    7. Oracle8i Server Application Developer's Guide, Oracle8i, 1998.

  • 8/14/2019 techniques tuning plsql apps twp

    26/26

    Oracle Corporation

    World Headquarters

    500 Oracle Parkway

    Redwood Shores, CA 94065U.S.A.

    Worldwide Inquiries:

    +1.650.506.7000

    Fax +1.650.506.7200

    http:// ww w.oracle.com/

    Copyright Oracle Corporation 1999

    All Rights Reserved

    This document is provided for informational purposes only, and

    the information herein is subject to change without notice.

    Please report any errors herein to Oracle Corporation. Oracle

    Corporation does not provide any warrant ies covering and

    specifically disclaims any liability in connection w ith t his

    document.

    Oracle and ConText are registered trademarks, and Oracle8i,

    Oracle8, Oracle7, PL/SQL, Pro*C and Oracle Developer are

    trademarks or registered trademarks of Oracle Corporation. All

    other company and product names mentioned are used for

    identification purposes only and may be trademarks of their

    respective owners.