Beruflich Dokumente
Kultur Dokumente
Performance Tuning
Version: 10gPERFTUNING/Handout/0708/1.0
Date: 09-07-08
Cognizant
500 Glen Pointe Center West
Teaneck, NJ 07666
Ph: 201-801-0233
www.cognizant.com
Handout – Oracle 10g PL/SQL Performance Tuning
TABLE OF CONTENTS
Introduction .....................................................................................................................................5
About this Module .........................................................................................................................5
Target Audience ...........................................................................................................................5
Module Objectives ........................................................................................................................5
Pre-requisites................................................................................................................................5
Page 2
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Page 3
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
References ..................................................................................................................................124
Websites ...................................................................................................................................124
Books ........................................................................................................................................124
Page 4
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Introduction
Target Audience
This module is designed for entry level trainees.
Module Objectives
After completing this module, you will be able to:
Explain the necessity of performance tuning
Identify various symptoms and problems which leads to performance tuning
Identify when the tuning has to be done
List the types of performance tuning
Pre-requisites
This module is designed for the trainees who have a good knowledge in Oracle 10g and
Oracle 10g PL/SQL.
Page 5
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Learning Objectives
After completing this session, you will be able to:
Explain performance tuning
State the types of performance tuning
Identify various symptoms which leads to performance tuning
List the goals of tuning
Introduction to Performance
The overall performance of an application is determined by these factors:
How many resources are available?
How many clients need the resource?
How long must they wait for the resource?
How long do they hold the resource?
As the number of requests rises, the time to service completion increases, if the number of
resources stays the same. To improve performance, you can either limit the demand rate to
maintain acceptable response times or you can add resources.
Page 6
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
When to Tune
There are two distinct types of tuning:
Proactive Monitoring: Proactive monitoring usually occurs on a regularly scheduled
interval, where a number of performance statistics are examined to identify whether
the system behavior and resource usage has changed. Proactive monitoring can also
be considered as proactive tuning.
Usually, monitoring does not result in configuration changes to the system, unless the
monitoring exposes a serious problem. In some situations, experienced performance
engineers can identify potential problems through statistics alone, although
accompanying performance degradation is usual.
Experimenting with or tweaking a system when there is no apparent performance
degradation as a proactive action can be a dangerous activity, resulting in
unnecessary performance drops. Tweaking a system should be considered reactive
tuning, and the steps for reactive tuning should be followed. Monitoring is usually part
of a larger capacity planning exercise, where resource consumption is examined to
see changes in the way the application is being used, and the way the application is
using the database and host resources.
Bottleneck Elimination: Tuning usually implies fixing a performance problem.
However, tuning should be part of the life cycle of an application—through the
analysis, design, coding, production, and maintenance stages. Oftentimes, the tuning
phase is left until the system is in production. At this time, tuning becomes a reactive
fire-fighting exercise, where the most important bottleneck is identified and fixed.
Usually, the purpose for tuning is to reduce resource consumption or to reduce the
elapsed time for an operation to complete. Either way, the goal is to improve the
effective use of a particular resource. In general, performance problems are caused by
the over-use of a particular resource. That resource is the bottleneck in the system.
Page 7
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
There are a number of distinct phases in identifying the bottleneck and the potential fixes.
Remember that the different forms of contention are symptoms that can be fixed by making
changes in the following places:
Changes in the application or the way the application is used
Changes in Oracle
Changes in the host hardware configuration
Often, the most effective way of resolving a bottleneck is to change the application.
Baselines
The most effective way to tune is to have an established performance baseline that can be used
for comparison if a performance issue arises. Most database administrators (DBAs) know their
system well and can easily identify peak usage periods. For example, the peak periods could be
between 10.00 AM and 12.00 PM and also between 1.30 PM and 3.00 PM. This could include a
batch window of 12.00 AM midnight to 6.00 AM. It is important to identify these peak periods at the
site and install a monitoring tool that gathers performance data for those high-load times.
Optimally, data gathering should be configured from when the application is in its initial trial phase
during the QA cycle. Otherwise, this should be configured when the system is first in production.
Ideally, baseline data gathered should include the following:
Application statistics (transaction volumes, response time)
Database statistics
Operating system statistics
Disk I/O statistics
Network statistics
This section provides information on tuning an Oracle Database system for performance. Topics
discussed here include the following:
Performance Planning
Oracle Instance Tuning
SQL Tuning
Page 8
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Performance Planning
Based on years of designing and performance experience, Oracle has designed a performance
methodology. Optimal system performance begins with design and continues throughout the life of
your system. Carefully consider performance issues during the initial design phase, and it will be
easier to tune your system during production. This brief section explains clear and simple activities
that can dramatically improve system performance. It discusses the following topics:
Understanding Investment Options: Performance improvement of a system can be
achieved by adding additional hardware. In many situations, new CPUs, memory, or
more disk drives can indeed provide an immediate performance improvement.
However, any performance increases achieved by adding hardware should be
considered a short-term relief to an immediate problem. If the demand and load rates
on the application continue to grow, then the chance that you will face the same
problem in the near future is very likely. Long-term, it is generally more valuable to
increase the efficiency of your application in terms of the number of physical resources
used for each business transaction.
Understanding Scalability: Scalability is a system’s ability to process more workload,
with a proportional increase in system resource usage. In other words, in a scalable
system, if you double the workload, then the system would use twice as many system
resources. This sounds obvious, but due to conflicts within the system, the resource
usage might exceed twice the original workload. When building applications, designers
and architects should aim for as close to perfect scalability as possible. This is
sometimes called linear scalability, where system throughput is directly proportional to
the number of CPUs.
System Architecture:There are two main parts to a system’s architecture:
o Hardware and Software Components: Today’s designers and architects are
responsible for sizing and capacity planning of hardware at each tier in a multitier
environment. It is the architect's responsibility to achieve a balanced design. The
same way computers have common hardware components, applications have
common functional components. By dividing software development into functional
components, it is possible to better comprehend the application design and
architecture.
o Configuring the right system architecture for your requirements: Configuring
the initial system architecture is a largely iterative process. Architects must satisfy
the system requirements within budget and schedule constraints. If the system
requires interactive users transacting business-making decisions based on the
contents of a database, then user requirements drive the architecture. If there are
few interactive users on the system, then the architecture is process-driven.
Page 9
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Application Design Principles: These are some of the design principles that are
involved in building applications:
o Simplicity in Application Design
o Data Modeling
o Table and Index Design
o Using Views
o SQL Execution Efficiency
o Implementing the Application
o Trends in Application Development
o Workload Testing, Modeling, and Implementation
o Database Design Principles
The initial design of the Oracle tables and indexes is the single most critical factor in overall
performance and unfortunately, the design can rarely be changed once the system is placed into
production use. So while the tuning techniques you will be discussing can help you maximize the
efficiency of your database engine, bear in mind that the initial design is the most important
performance factor.
When a database is initially analyzed, the designer will often apply the normalization rules
developed by E.F.Codd and C.J.Date. Their normalization study resulted in a set of table
definitions that made it easier to design tables with controlled redundancy.
In the 1970s, database redundancy was difficult and expensive. As a result, database designers
were taught to create databases in Third Normal Form (3NF), which prevented data duplication in
multiple tables. But although a 3NF database was totally free of redundancy, the database queries
could run very slowly because of the extra navigation required to access information. Over the
1980s and 1990s, database designers became more liberal with the introduction of redundant data
to speed database queries.
Page 10
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
After starting an instance, Oracle associates the instance with the specified database. This is
called mounting the database. The database is then ready to be opened, which makes it
accessible to authorized users. Only the database administrator can start up an instance and open
the database. If a database is open, the database administrator can shut down the database so
that it is closed. When a database is closed, users cannot access the information that it contains.
Security for database startup and shutdown is controlled through connections to Oracle with
administrator privileges. Normal users do not have control over the current status of an Oracle
database.
Instance Tuning
This instance-tuning phase of Oracle tuning examines the overall database and the instance-wide
parameters that affect performance.
Page 11
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
You have to remember that all Oracle instances are generally constrained by I/O operations. I/O is
the single most dramatic component of Oracle performance, and any initialization parameters that
can be used in order to reduce I/O will improve the performance of the database.
SQL Tuning
An important facet of database system performance tuning is the tuning of SQL statements. SQL
tuning involves three basic steps:
Identifying high load or top SQL statements that are responsible for a large share of
the application workload and system resources, by reviewing past SQL execution
history available in the system.
Verifying that the execution plans produced by the query optimizer for these
statements perform reasonably.
Implementing corrective actions to generate better execution plans for poorly
performing SQL statements.
These three steps are repeated until the system performance reaches a satisfactory level or no
more statements can be tuned.
Typically, SQL statements issued by OLTP applications operate on relatively few rows at a time. If
an index can point to the exact rows that are required, then Oracle can construct an accurate plan
to access those rows efficiently through the shortest possible path. In decision support system
(DSS) environments, selectivity is less important, because they often access most of a table's
rows. In such situations, full table scans are common, and indexes are not even used.
During the evaluation process, the query optimizer reviews statistics gathered on the system to
determine the best data access path and other considerations. You can override the execution
plan of the query optimizer with hints inserted in SQL statement.
Page 12
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Reduce the Workload: SQL tuning commonly involves finding more efficient ways to process the
same workload. It is possible to change the execution plan of the statement without altering the
functionality to reduce the resource consumption.
Balance the Workload: Systems often tend to have peak usage in the daytime when real users
are connected to the system and low usage in the nighttime. If noncritical reports and batch jobs
can be scheduled to run in the nighttime and their concurrency during day time reduced, then it
frees up resources for the more critical programs in the day.
Parallelize the Workload: Queries that access large amounts of data (typical data warehouse
queries) often can be parallelized. This is extremely useful for reducing the response time in low
concurrency data warehouse. However, for OLTP environments, which tend to be high
concurrency, this can adversely, impact other users by increasing the overall resource usage of
the program.
The goals of SQL tuning focus on improving the execution plan to fetch the rows with the smallest
number of database "touches",
Remove unnecessary large-table full-table scans: Unnecessary full-table scans
cause a huge amount of unnecessary I/O and can drag-down an entire database. The
tuning expert first evaluates the SQL based on the number of rows returned by the
query. If the query returns less than 40 percent of the table rows, it needs tuning. The
most common tuning remedy for unnecessary full-table scans is adding indexes.
Standard b-tree indexes can be added to tables, and bitmapped and function-based
indexes can also eliminate full-table scans. In some cases, an unnecessary full-table
scan can be forced to use an index by adding an index hint to the SQL statement.
Cache small-table full-table scans: In cases where a full-table scan is the fastest
access method, the administrator should ensure that a dedicated data buffer is
available for the rows. In Oracle7, you can issue "alter table xxx cache". In Oracle8
and beyond, the small table can be cached by forcing it into the KEEP pool.
Verify optimal index usage: This is especially important when using the rule-based
optimizer. Oracle sometimes has a choice of indexes, and the tuning professional
must examine each index and ensure that Oracle is using the proper index.
Page 13
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Materialize your aggregations and summaries for static tables: One features of
the Oracle 10g SQL Access advisor is recommendations for new indexes and
suggestions for materialized views. Materialized views pre-join tables and pre-
summarize data, a real silver bullet for data mart reporting databases where the data
is only updated daily.
Summary
Oracle experts generally use a top-down approach for tuning.
Performance tuning are of two types:
o Proactive monitoring
o Bottleneck elimination
SQL tuning targeting factors are as follows:
o Reduce the workload
o Balance the workload
o Parallelize the workload
Page 14
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Learning Objectives
After completing this session, you will be able to:
List various methods involved in performance improvement
Identify top ten mistakes found in Oracle systems
Define SQL parsing
Explain the enforcing of soft parsing
List the steps in the tuning process
Identify the types of parsing.
Explain the SQL parsing process
State the tips for reducing hard parsing
Introduction
Oracle performance methodology helps you to pinpoint performance problems in your Oracle
system. This involves identifying bottlenecks and fixing them. Performance improvement, by its
nature, is iterative. For this reason, removing the first bottleneck might not lead to performance
improvement immediately, because another bottleneck might be revealed. Also, in some cases, if
serialization points move to a more inefficient sharing mechanism, then performance could
degrade. With experience, and by following a rigorous method of bottleneck elimination,
applications can be debugged and made scalable.
Performance problems generally result from either a lack of throughput, unacceptable user/job
response time, or both. The problem might be localized between application modules, or it might
be for the entire system. Before looking at any database or operating system statistics, it is crucial
to get feedback from the most important components of the system: the users of the system and
the people ultimately paying for the application.
Page 15
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
The Oracle performance improvement method can be applied until performance goals are met. It
takes time and experience to develop the necessary skills to accurately pinpoint critical bottlenecks
in a timely manner. Today's systems are so different and complex that hard and fast rules for
performance analysis cannot be made. In essence, the Oracle performance improvement method
defines a way of working, but not a definitive set of rules. With bottleneck detection, the only rule is
that there are no rules! The best performance engineers use the data provided and think laterally
to determine performance problems.
This method identifies the biggest bottleneck and uses an objective approach to performance
improvement. The focus is on making large performance improvements by increasing application
efficiency and eliminating resource shortages and bottlenecks. In this process, it is anticipated that
minimal (less than 10%) performance gains are made from instance tuning, and large gains (100%
+) are made from isolating application inefficiencies.
Page 16
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
The Automatic Database Diagnostic Monitor (ADDM) analyzes data in the Automatic Workload
Repository (AWR) to identify potential performance bottlenecks. For each of the identified issues it
locates the root cause and provides recommendations for correcting the problem. An ADDM
analysis task is performed and its findings and recommendations stored in the database every
time an AWR snapshot is taken provided the STATISTICS_LEVEL parameter is set to TYPICAL
or ALL. The ADDM analysis includes the following:
CPU load
Memory usage
I/O usage
Resource intensive SQL
Resource intensive PL/SQL and Java
RAC issues
Application issues
Database configuration issues
Concurrency issues
Object contention
For example, suppose a DBA receives a call from a user complaining that the system is slow. The
DBA simply examines the latest ADDM report to see which of the recommendations should be
implemented to solve the problem. The following steps illustrate how a performance engineer
might look for bottlenecks without using automatic diagnostic features. These steps are only
intended as a guideline for the manual process.
With experience, performance engineers add to the steps involved. This analysis assumes that
statistics for both the operating system and the database have been gathered.
1. Is the response time/batch run time acceptable for a single user on an empty or lightly
loaded machine?
If it is not acceptable, then the application is probably not coded or designed optimally, and
it will never be acceptable in a multiple user situation when system resources are shared.
In this case, get application internal statistics, and get SQL Trace and SQL plan
information. Work with developers to investigate problems in data, index, transaction SQL
design, and potential deferral of work to batch/background processing.
2. Is all the CPU being utilized?
If the kernel utilization is over 40%, then investigate the operating system for network
transfers, paging, swapping, or process thrashing. Otherwise, move onto CPU utilization in
user space. Check to see if there is any non-database jobs consuming CPU on the
machine limiting the amount of shared CPU resources, such as backups, file transforms,
print queues, and so on. After determining that the database is using most of the CPU,
Page 17
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
investigate the top SQL by CPU utilization. These statements form the basis of all future
analysis. Check the SQL and the transactions submitting the SQL for optimal execution.
Oracle provides CPU statistics in V$SQL and V$SQLSTATS.
If the application is optimal and there are no inefficiencies in the SQL execution, consider
rescheduling some work to off-peak hours or using a bigger machine.
3. At this point, the system performance is unsatisfactory, yet the CPU resources are not fully
utilized.
In this case, you have serialization and unscalable behavior within the server. Get the
WAIT_EVENTS statistics from the server, and determine the biggest serialization point. If
there are no serialization points, then the problem is most likely outside the database, and
this should be the focus of investigation. Elimination of WAIT_EVENTS involves modifying
application SQL and tuning database parameters. This process is very iterative and
requires the ability to drill down on the WAIT_EVENTS systematically to eliminate
serialization points.
Page 18
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
REDO log setup problems: Many sites run with too few redo logs that are too small.
Small redo logs cause system checkpoints to continuously put a high load on the
buffer cache and I/O system. If there are too few redo logs, then the archive cannot
keep up, and the database will wait for the archive process to catch up.
Serialization of data blocks in the buffer cache due to lack of free lists, free list
groups, transaction slots (INITRANS), or shortage of rollback segments: This is
particularly common on INSERT-heavy applications, in applications that have raised
the block size above 8K, or in applications with large numbers of active users and few
rollback segments. Use automatic segment-space management (ASSM) to and
automatic undo management solves this problem.
Long full table scans: Long full table scans for high-volume or interactive online
operations could indicate poor transaction design, missing indexes, or poor SQL
optimization. Long table scans, by nature, are I/O intensive and unscalable.
High amounts of recursive (SYS) SQL: Large amounts of recursive SQL executed
by SYS could indicate space management activities, such as extent allocations, taking
place. This is unscalable and impacts user response time. Use locally managed
tablespaces to reduce recursive SQL due to extent allocation. Recursive SQL
executed under another user Id is probably SQL and PL/SQL, and this is not a
problem.
Deployment and migration errors: In many cases, an application uses too many
resources because the schema owning the tables has not been successfully migrated
from the development environment or from an older implementation. Examples of this
are missing indexes or incorrect statistics. These errors can lead to sub-optimal
execution plans and poor interactive user performance.
SQL Parsing
Whenever a statement is executed, Oracle follows a methodology to evaluate the statement in
terms of syntax, validity of objects being referred and of course, privileges to the user. Apart from
this, Oracle also checks for identical statements that may have been fired, with the intention of
reducing processing overheads. All this takes place in a fraction of a second, even less, without
the user knowing what is happening to the statement that was fired. This process is known as
Parsing.
Types of Parsing
All statements, DDL or DML, are parsed whenever they are executed. The only key fact is that
whether it was a Soft (statement is already parsed and available in memory) or a Hard (all parsing
steps to be carried out) parse. Soft parse will considerably improve the system performance where
as frequent Hard parsing will affect the system. Reducing hard parsing will improve the resource
utilization and optimize the SQL code.
Parsing Process
Oracle internally does the following to arrive at the output of an SQL statement.
Syntactical check. The query fired is checked for its syntax.
Semantic check. Checks on the validity of the objects being referred in the statement
and the privileges available to the user firing the statement. This is a data dictionary
check.
Allocation of private SQL area in the memory for the statement.
Page 19
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Generating a parsed representation of the statement and allocating Shared SQL area.
This involves finding an optimal execution path for the statement.
In point four, Oracle first checks if the same statement is already parsed and existing in the
memory. If found the parsed representation will be picked up and the statement executed
immediately (Soft parse). If not found, then the parsed representation is generated and stored in a
shared SQL area (Part of shared pool memory in SGA), the statement is then executed (Hard
parse). This step involves the optimization of the statement, the one that decides the performance.
Identical Statements
Oracle does the following to find identical statements to decide on a soft or a hard parse.
When a new statement is fired, a hash value is generated for the text string. Oracle
checks if this new hash value matches with any existing hash value in the shared pool.
Next, the text string of the new statement is compared with the hash value matching
statements. This includes comparison of case, blanks and comments present in the
statements.
If a match is found, the objects referred in the new statement are compared with the
matching statement objects. Tables of the same name belonging to different a schema
will not account for a match.
The bind variable types of the new statement should be of same type as the identified
matching statement.
If all of the above is satisfied, Oracle re-uses the existing parse (soft). If a match is not
found, Oracle goes through the process of parsing the statement and putting it in the
shared pool (hard).
Collection types and object types increase your productivity by allowing for realistic data modeling.
Complex real-world entities and relationships map directly into object types. A well-constructed
object model can improve application performance by eliminating table joins, reducing round trips,
and the like.
%TYPE: For scalar structures
Page 20
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Check for statements with a lot of executions. It is bad to have the PARSE_CALLS value in the
above statement close to the EXECUTIONS value. The above query will fire only for DML
statements (to check on other types of statements use the appropriate command type number).
Also ignore Recursive calls (dictionary access), as it is internal to Oracle.
The earlier query will also show recursive SQL being fired internally by Oracle.
Summary
Steps in performance tuning methods are as follows:
o Get feedback from users.
o Gather the complete statistics of the system.
o Sanity-check the operating systems of all machines involved.
o Check for the existence of Oracle top ten mistakes in your system.
o Build a conceptual model of the system depending on the symptoms.
SQL parser is a component of SQL compiler. It checks for correctness of syntax for
the executed query.
Three stages of processing an SQL query are as follows:
o Parsing
o Executing
o Fetching
Page 21
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Page 22
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Learning Objectives
After the completion of this session, you would be able to:
Define SQL Tuning
Write effective SQL statements
List the best practices to be followed while writing SQL
Identify Oracle SQL performance tuning tips
Page 23
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Oracle8i and later has a great feature that stores information on long-running queries currently
active in the V$SESSION_LONGOPS view.
WHERE sql_address=address
AND sql_hash_value=hash_value
ORDER BY address, hash_value, child_number
Verifying that the execution plans produced by the query optimizer for these
statements perform reasonably.
Implementing corrective actions to generate better execution plans for poorly
performing SQL statements.
These three steps are repeated until the system performance reaches a satisfactory level or no
more statements can be tuned.
For example, assume you are trying to find the names of customers who have orders. Your query
has to be based on two tables: CUSTOMER and CUST_ORDER. Using DISTINCT, your query would
be written as follows:
SELECT DISTINCT C.CUST_NBR, C.NAME
FROM CUSTOMER C, CUST_ORDER O
WHERE C.CUST_NBR = O.CUST_NBR;
The corresponding execution plan for this query is as follows. Note the SORT operation, which is a
result of DISTINCT being used.
Query Plan
-----------------------------------------
SELECT STATEMENT Cost = 3056
SORT UNIQUE
MERGE JOIN
INDEX FULL SCAN IND_ORD_CUST_NBR
SORT JOIN
Page 24
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Here is the execution plan for the EXISTS version of the query. Look at the cost of this query
versus the earlier DISTINCT query, and notice the performance improvement.
Query Plan
---------------------------------------
SELECT STATEMENT Cost = 320
FILTER
TABLE ACCESS FULL CUSTOMER
INDEX RANGE SCAN IND_ORD_CUST_NBR
The version of the query using EXISTS is less than one-ninth as costly as the version using
DISTINCT. This is because the sort has been avoided.
EXISTS Versus IN
The following query uses IN to delete the orders for customers in region 5:
Page 25
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
The execution plan for the EXISTS version of the query is as follows:
Query Plan
--------------------------------------------
DELETE STATEMENT Cost = 1
DELETE CUST_ORDER
FILTER
TABLE ACCESS FULL CUST_ORDER
TABLE ACCESS BY INDEX ROWID CUSTOMER
INDEX UNIQUE SCAN CUSTOMER_PK
Notice the cost difference between the two queries. The IN version of the query has a cost of 3,
while the EXISTS version of the query has a cost of only 1. When the EXISTS clause is used, the
execution plan is driven by the outer table, whereas when the IN clause is used, the execution plan
is driven by the table in the subquery. The EXISTS query will almost always be faster than the IN
query, except for cases when the table in the subquery has very few rows as compared to the
outer table.
Let's look at an example illustrating the advantage of WHERE over HAVING. Here is a query with the
HAVING clause that reports the number of orders in the year 2000:
SELECT YEAR, COUNT(*) FROM ORDERS
GROUP BY YEAR HAVING YEAR = 2000;
YEAR COUNT(*)
------ --------
2000 720
Page 26
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Now, look at that same query, but with the year restriction in the WHERE clause:
SELECT YEAR, COUNT(*) FROM ORDERS
WHERE YEAR = 2000 GROUP BY YEAR;
YEAR COUNT(*)
----- --------
2000 720
With the HAVING clause, the query performs the group operation first, and then filters the groups
for the condition specified. The WHERE clause version of the query filters the rows before
performing the group operation. The result of filtering with the WHERE clause is that there are fewer
rows to summarize, and consequently the query performs better.
However, you should note that not all types of filtering can be achieved using the WHERE clause.
Sometimes, you may need to summarize the data first, and then filter the summarized data based
upon the summarized values. In such situations, you have to filter using the HAVING clause,
because only the HAVING clause can "see" summarized values. Moreover, there are situations
when you may need to use the WHERE clause and the HAVING clause together in a query to filter
the results the way you want.
Let's look an example to understand this issue better. The following query uses UNION to return a
list of orders where the sale price exceeds $50.00 or where the customer is located in region 5:
SELECT ORDER_NBR, CUST_NBR FROM CUST_ORDER WHERE SALE_PRICE > 50
UNION
SELECT ORDER_NBR, CUST_NBR FROM CUST_ORDER
WHERE CUST_NBR IN
(SELECT CUST_NBR FROM CUSTOMER WHERE REGION_ID = 5);
Page 27
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
ORDER_NBR CUST_NBR
----------------- ----------------
1000 1
1001 1
1002 5
1003 4
1004 4
1005 8
1006 1
1007 5
1008 5
1009 1
10 rows selected.
The following query uses UNION ALL instead of UNION to get the same information:
SELECT ORDER_NBR, CUST_NBR FROM CUST_ORDER WHERE SALE_PRICE > 50
UNION ALL
SELECT ORDER_NBR, CUST_NBR FROM CUST_ORDER
WHERE CUST_NBR IN
(SELECT CUST_NBR FROM CUSTOMER WHERE REGION_ID = 5);
ORDER_NBR CUST_NBR
-------------------- ------------------
1001 1
1003 4
1005 8
1009 1
1012 1
1017 4
1021 8
1029 1
1001 1
Page 28
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
1000 1
1002 5
1003 4
1004 4
1006 1
1007 5
1008 5
16 rows selected.
Note the duplicate rows in the output. However, note also that UNION ALL performs better than
UNION, as you can see from the following execution plan:
Query Plan
------------------------------------------------------------------------
SELECT STATEMENT Cost = 4
UNION-ALL
TABLE ACCESS FULL CUST_ORDER
HASH JOIN
TABLE ACCESS FULL CUSTOMER
TABLE ACCESS FULL CUST_ORDER
Compare this execution plan with its cost of 4 with the previous plan and its cost of 8. You can see
that the extra operation (SORT UNIQUE) in the UNION makes it run slower than UNION ALL.
These two statements are similar, but not "identical"—the customer ID numbers are different,
therefore Oracle has to parse twice.
As the only difference between these statements is the value used for the customer number, this
application could be rewritten to use bind variables. In that case, the SQL statement in question
could be as follows:
SELECT * FROM CUSTOMER WHERE CUST_NBR = :X;
Oracle needs to parse this statement only once. The actual customer numbers would be supplied
after parsing for each execution of the statement. Multiple, concurrently executing programs could
share the same copy of this SQL statement while at the same time supplying different customer
number values.
Page 29
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
In a multi-user application, situations such as the one described here are very common, and
overall performance can be significantly improved by using bind variables, thereby reducing
unnecessary parsing.
When you select data from two or more tables, you should specify which table each column
belongs to. Otherwise, if the two tables have columns with the same name, you will end up with an
error:
SELECT CUST_NBR, NAME, ORDER_NBR
FROM CUSTOMER, CUST_ORDER;
The error in this case occurs because both the CUSTOMER and CUST_ORDER tables have columns
named CUST_NBR. Oracle cannot tell which CUST_NBR column you are referring to. To fix this
problem, you could rewrite this statement as follows:
SELECT CUSTOMER.CUST_NBR, CUSTOMER.NAME, CUST_ORDER.ORDER_NBR
FROM CUSTOMER, CUST_ORDER
WHERE CUSTOMER.CUST_NBR = CUST_ORDER.CUST_NBR;
3 rows selected.
Note the use of the table name to qualify each column name. This eliminates any ambiguity as to
which CUST_NBR column the query is referring to.
Instead of qualifying column names with full table names, you can use table aliases, as in the
following example:
SELECT C.CUST_NBR, C.NAME, O.ORDER_NBR
FROM CUSTOMER C, CUST_ORDER O
WHERE C.CUST_NBR = O.CUST_NBR;
Page 30
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
3 rows selected.
The letters "C" and "O" in this example are table aliases. You can specify these aliases following
their respective table names in the FROM clause, and they can be used everywhere else in the
query in place of the table name. Table aliases provide a convenient shorthand notation, allowing
your queries to be more readable and concise.
An important thing to remember while using table aliases is that if you define aliases in the FROM
clause, you must use only those aliases, and not the actual table names, in the rest of the query. If
you alias a table and then use the actual table name in a query, you will encounter errors. For
example:
SELECT C.CUST_NBR, C.NAME, O.ORDER_NBR
FROM CUSTOMER C, CUST_ORDER O
WHERE CUSTOMER.CUST_NBR = CUST_ORDER.CUST_NBR;
3 rows selected.
This is where the performance aspect of using table aliases comes into play. Since the query
doesn't qualify the columns NAME and ORDER_NBR, Oracle has to search both the CUSTOMER
and CUST_ORDER tables while parsing this statement to find which table each of these columns
belongs to. The time required for this search may be negligible for one query, but it does add up if
Page 31
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
you have a number of such queries to parse. It is good programming practice to qualify all columns
in a query with table aliases, even those that are not ambiguous, so that Oracle can avoid this
extra search when parsing the statement.
An index is typically stored separately from the table for which the index was created. An index’s
main purpose is to improve the performance of the data retrieval. Indexes can created or dropped
with no effect on the data. However, after the index is dropped the performance of the data
retrieval might be slowed. Indexes do take physical space and sometimes they may take more
space than the table itself. Therefore, they need to be considered when estimating the size of the
database.
Page 32
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
As shown in the figure, the NAME index is reference to resolve the location of all names equal to
’SMITH’. After the location is determined; the data can retrieved quickly from the table. A full
table scan would occur if there was no index on the table and the same query was executed,
which means that every row of data would be read to retrieve the information pertaining to all the
individuals with the name ‘SMITH’.
Do not use indexes as a remedy for all. Application developers sometimes think that performance
will improve if they create more indexes. If a single programmer creates an appropriate index, then
this might indeed improve the application's performance. However, if 50 programmers each create
an index, then application performance will probably be hampered.
Page 33
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Columns that are frequently manipulated should not be indexed. Maintenance on the
index can become expensive.
TIP 1 (Best Tip): SQL cannot be shared within Oracle unless it is absolutely identical. Statements
must have match exactly in case, white space and underlying schema objects to be shared within
Oracle's memory. Oracle avoids the parsing step for each subsequent use of an identical
statement.
Use SQL standards within an application: Rules like the following are easy to
implement and will allow more sharing within Oracle's memory.
o Using a single case for all SQL verbs
o Beginning all SQL verbs on a new line
o Right or left aligning verbs within the initial SQL verb
o Separating all words with a single space
Use bind variables: The values of bind variables do not need to be the same for two
statements to be considered identical. Bind variables are not substituted until a
statement has been successfully parsed.
Sharable SQL SELECT * FROM emp WHERE emp_no = :B1; Bind value: 123
Use a standard approach to table aliases: If two identical SQL statements vary
because an identical table has two different aliases, then the SQL is different and will
not be shared.
Page 34
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Use table aliases and prefix all column names by their aliases when more than one
table is involved in a query. This reduces parse time AND prevents future syntax
errors if someone adds a column to one of the tables with the same name as a column
in another table. (ORA-00918: COLUMN AMBIGUOUSLY DEFINED)
TIP 2: Beware of WHERE clauses which do not use indexes at all. Even if there is an index over a
column that is referenced by a WHERE clause included in this section, Oracle will ignore the index.
All of these WHERE clauses can be re-written to use an index while returning the same values. In
other words, do not perform operations on database objects referenced in the WHERE clause.
Page 35
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
TIP 3: Do not forget to tune views. Views are SELECT statements and can be tuned in just the
same way as any other type of SELECT statement can be. All tuning applicable to any SQL
statement are equally applicable to views.
TIP 4: Avoid including a HAVING clause in SELECT statements. The HAVING clause filters
selected rows only after all rows have been fetched. Using a WHERE clause helps reduce
overheads in sorting, summing, etc. HAVING clauses should only be used when columns with
summary operations applied to them are restricted by the clause.
TIP 5: Minimize the number of table lookups (subquery blocks) in queries, particularly if your
statements include subquery SELECTs or multicolumn UPDATEs.
SELECT emp_name
FROM emp
WHERE emp_cat = (SELECT MAX (category)
Separate
FROM emp_categories)
Subqueries
AND emp_range = (SELECT MAX (sal_range)
FROM emp_categories)
AND emp_dept = 0020;
SELECT emp_name
FROM emp
Combined WHERE (emp_cat, sal_range)
Subqueries = (SELECT MAX (category), MAX (sal_range)
FROM emp_categories)
AND emp_dept = 0020;
TIP 6: Consider the alternatives EXISTS, IN and table joins when doing multiple table joins.
None of these are consistently faster; it depends on your data. If there is a poor performer here, it
Page 36
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
(Note, this query returns the employee names from each department in department category 'A'.)
SELECT emp_name
FROM emp E
WHERE EXISTS ( SELECT 'X'
FROM dept
WHERE dept_no = E.dept_no
AND dept_cat = 'A');
SELECT emp_name
FROM emp E
WHERE dept_no IN ( SELECT dept_no
FROM dept
WHERE dept_no = E.dept_no
AND dept_cat = 'A');
SELECT emp_name
FROM dept D, emp E
WHERE E.dept_no = D.dept_no
AND D.dept_cat = 'A';
TIP 7: Avoid joins that require the DISTINCT qualifier on the SELECT list in queries which are
used to determine information at the owner end of a one-to-many relationship. The DISTINCT
operator causes Oracle to fetch all rows satisfying the table join and then sort and filter out
duplicate values. EXISTS is a faster alternative, because the Oracle optimizer realizes when the
subquery has been satisfied once, there is no need to proceed further and the next matching row
can be fetched.
(Note: This query returns all department numbers and names which have at least one employee.)
Do Not Use Use
SELECT DISTINCT dept_no, SELECT dept_no, dept_name
dept_name FROM dept D
FROM dept D, WHERE EXISTS (
emp E SELECT 'X'
WHERE D.dept_no = E.dept_no; FROM emp E
WHERE E.dept_no = D.dept_no);
TIP 8: Consider whether a UNION ALL will suffice in place of a UNION. The UNION clause forces
all rows returned by each portion of the UNION to be sorted and merged and duplicates to be
Page 37
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
filtered before the first row is returned. A UNION ALL simply returns all rows including duplicates
and does not have to perform any sort, merge or filter. If your tables are mutually exclusive
(include no duplicate records), or you don't care if duplicates are returned, the UNION ALL is
much more efficient.
TIP 9: Consider using DECODE to avoid having to scan the same rows repetitively or join the same
table repetitively. Note, DECODE is not necessarily faster as it depends on your data and the
complexity of the resulting query. Also, using DECODE requires you to change your code when new
values are allowed in the field.
SELECT COUNT(*)
FROM emp
WHERE status = 'Y'
AND emp_name LIKE 'SMITH%';
----------
SELECT COUNT(*)
FROM emp
WHERE status = 'N'
AND emp_name LIKE 'SMITH%';
SELECT COUNT(DECODE(status, 'Y', 'X', NULL)) Y_count,
COUNT(DECODE(status, 'N', 'X', NULL)) N_count
FROM emp
WHERE emp_name LIKE 'SMITH%';
TIP 10: Oracle automatically performs simple column type conversions (or casting) when it
compares columns of different types. Depending on the type of conversion, indexes may not be
used. Make sure you declare your program variables as the same type as your Oracle columns, if
the type is supported in the programming language you are using.
Page 38
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Data type
of
Index
field in Your Query After Implicit Conversion
Used?
where
clause
SELECT ...
emp_no SELECT ...
FROM emp
indexed FROM emp YES
WHERE emp_no = WHERE emp_no =
numeric
'123'; TO_NUMBER('123');
SELECT ...
emp_type SELECT ...
FROM emp NO!
indexed FROM emp
WHERE emp_type WHERE TO_NUMBER (emp_type) =
varchar2
= 123; 123;
Tip 11: Avoid the LIKE predicate = Always replace a "like" with equality, wherever appropriate
Tip 12: Use of OR Instead of UNION: The OR EXISTS subquery takes long time to execute.
or exists
(select 'x'
from ps_jrnl_header
where business_unit_iu=a.business_unit_iu
and journal_id= a.journal_id
and journal_date=a.journal_date
and unpost_seq= a.unpost_seq
and jrnl_hdr_status='E')
Notice the long runtime for the statement. It would not it be nice to make the statement go faster?
Luckily, the fix is simple. If you have the access to change the code (that is, you are not running a
third-party package), then use a UNION statement to implement the OR in the WHERE clause as two
separate queries:
select ...........
from ps_jrnl_header a
where jrnl_hdr_status ='E'
Page 39
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
UNION
select .....
from ps_jrnl_header a, ps_jrnl_header b
where b.business_unit_iu
=a.business_unit_iu
and b.journal_id=a.journal_id
and b.journal_date=a.journal_date
and b.unpost_seq=a.unpost_seq
and a.jrnl_hdr_status='E'
and b.jrnl_hdr_status != 'E';
The reason for the performance improvement is that the UNION allows the optimizer to perform
two simple operations to return the rows, whereas the more complex OR construct has confused
the optimizer into using a less optimal execution plan.
In this example, if ACCT_NAME represents a unique key index and COST_CENTER represents a
single column non-unique index, the unique key index would make the ACCT table the driving
table.
If both COST_CENTER and ACCT_NAME were single column, non-unique indexes, the rule-based
optimizer would select the TRANS table as the driving table, because it is listed last in the FROM
clause. Having the TRANS table as the driving table would likely mean a longer response time for a
query, because there is usually only one ACCT row for a selected account name but there are likely
to be many transactions for a given cost center.
With the rule-based optimizer, if the index rankings are identical for both tables, Oracle simply
executes the statement in the order in which the tables are parsed. As the parser processes table
names from right to left, the table name that is specified last (For example, DEPT in the earlier
example is actually the first table processed that is, the driving table).
Page 40
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
The response time following the re-ordering of the tables in the FROM clause is as follows:
SELECT COUNT(*) FROM trans b, acct a WHERE b.cost_center=
'MASS' AND a.acct_name = 'MGA' AND a.acct_name =
b.acct_name;
It is important that the table that is listed last in the FROM clause is going to return the fewest
number of rows.
Identify incorrect driving Index and fix it: The way you specify conditions in the
WHERE clauses of your SELECT statements has a major impact on the performance of
your SQL, because the order in which you specify conditions impacts the indexes the
optimizer choose to use. The effect is very similar to that from the ordering of tables in
the FROM clause. Consider the following example:
SELECT COUNT(*)
FROM trans
WHERE cost_center = 'MASS'
AND bmark_id = 9;
The index that has the column that is listed first in the WHERE CLAUSE will drive the query. In this
statement, the indexed entries for COST_CENTER = `MASS' will return significantly more rows
than those for BMARK_ID=9, which will return at most only one or two rows.
The following query reverses the order of the conditions in the WHERE clause, resulting in a much
faster execution time.
SELECT COUNT(*)
FROM trans
WHERE bmark_id = 9
AND cost_center = 'MASS';
Analyze tables periodically to improve the performance: Imagine that you are
consulting at a site with a table TRANS that has a column called STATUS. The column
has two possible values: `O' for Open Transactions that have not been posted and `C'
for closed transactions that have already been posted and that require no further
action. There are over one million rows that have a status of `C', but only 100 rows
that have a status of `O' at any point in time.
Page 41
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
The site has the following SQL statement that runs many hundreds of times daily. The response
time is dismal, and you have been called in to "make it go faster."
If you inform Oracle of the data skewness by specifying the option FOR ALL INDEXED COLUMNS
when you run the ANALYZE command or when you invoke the DBMS_STATS package, Oracle will
be made aware of the skewness of the data; that is, the number of rows that exist for each value
for each indexed column. In our scenario, the STATUS column is indexed.
After analyzing the table and computing statistics for all indexed columns, the cost-based optimizer
is aware that there are only 100 or so rows with a status of `O', and it will accordingly use the index
on that column. Use of the index on the STATUS column results in the following, much faster,
query response:
Typically the cost-based optimizer will perform a full table scan if the value selected for a column
has over 12% of the rows in the table, and will use the index if the value specified has less than
12% of the rows. The cost-based optimizer selections are not quite as firm as this, but as a rule of
thumb this is the typical behavior that the cost-based optimizer will follow.
Note: Re-analyzing tables and indexes can be almost as dangerous as adjusting your indexing,
and should ideally be tested in a copy of the production database prior to being applied to the
production database.
Tables and indexes with many deletes: Oracle is similar to many other databases in
that there are performance issues with deletes. Oracle has a high water mark, which
represents the highest number of rows ever inserted into the table. This high-water
mark can have an impact on performance.
Consider the following example, which takes 5.378 seconds to read a table with
151,070 rows:
SELECT COUNT(*) FROM YYYY;
151070
real: 5378
Page 42
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
It just happens that all 150,000 rows have the STATE column set to `VIC', and that the table has an
index on the STATE column. If you use a WHERE clause to force the count to use the index on the
STATE, then it takes 16.884 seconds:
SELECT COUNT(*) FROM YYYY WHERE STATE='VIC';
---------
151070
real: 16884
The index scan took about three times longer than the full table scan. Now let's delete all of the
rows, so that the result is an empty table:
DELETE FROM YYYY;
real: 55277
Now that you have an empty table, let's count all the rows again:
SELECT COUNT(*) FROM YYYY;
---------
0
real: 5117
Notice that it takes the same amount of time to count zero rows as it took to count from the table
when it was completely populated. This is because, when performing a full table scan, Oracle
reads as far as the table's high-water mark, and the high-water mark has not changed.
Just as before, it takes the same amount of time to count zero rows as it took to count the original
150,000. This is because the index entries are logically deleted, but still exist physically.
To avoid the types of performance problems rebuild a table, and its indexes, whenever the table
has undergone many deletes. If index columns are frequently updated, you should also re-build
the indexes, because an update forces a logical delete in the index followed by an insert of the
new, updated entry.
To detect which tables have many deletes and updates, you can run the following SELECT
statement:
SELECT sql_text, executions
FROM v$sqlarea
WHERE UPPER(sql_text) LIKE 'DELETE%'
OR
UPPER(sql_text) LIKE 'UPDATE%';
Page 43
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Full-table scans may at times be more efficient than the use of indexes if the table is
relatively small in size, as Oracle can read all the data with one I/O operation.
Note: A full table scan is typically able to read over 100 rows of table information per block. Added
to this, the DB_FILE_MULTIBLOCK_READ_COUNT parameter allows Oracle to read many blocks
with one physical disk read. You may be reading 800 rows with each physical read from disk. In
comparison, an index will potentially perform one physical read for each row returned from the
table.
Functions applied to indexed columns in the WHERE clause do not take advantage of
the index unless you use the MIN or MAX function. In the following example, the TRUNC
function disables the index.
Do not use:
SELECT account_name, trans_date, amount
FROM transaction
WHERE TRUNC(trans_date) = TRUNC(SYSDATE);
Use:
SELECT account_name, trans_date, amount
FROM transaction
WHERE trans_date BETWEEN TRUNC(SYSDATE)
AND TRUNC(SYSDATE) + .99999;
Page 44
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Summary
SQL tuning is the process of tuning the SQL statements that access the database.
Follow a standard approach to write your SQL statements:
o Use a single case for all SQL verbs
o Begin all SQL verbs on a new line
o Right or left aligning verbs within the initial SQL verbs
SQL performance tuning tips are as follows:
o Identify incorrect driving table and fix it
o Identify incorrect driving index and fix it
o Analyze tables and indexes periodically
o Identify tables and indexes with many deletes
o Watch out for table records before creating indexes
Page 45
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Learning Objectives
After completing this session, you will be able to:
Define an optimizer
Identify the types of optimizer
Analyze execution plan
Apply optimizer hints to override CBO
Introduction
The SQL processing architecture contains the following main components:
Parser
Optimizer
Row Source Generator
SQL Execution Engine
The parser, the optimizer and the row source generator form the SQL Compiler. The SQL
Compiler compiles the SQL statements into a shared cursor, which is associated with the
execution plan.
Page 46
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Parser
The parser performs two functions:
Syntax analysis: Checks SQL statements for correct syntax
Semantic analysis: Checks that current database objects and object attributes
references are correct
Optimizer
The optimizer uses internal rules or costing methods to determine the most efficient way of
producing the result of the query. The output from the optimizer is a plan that describes an
optimum method of execution. The Oracle server provides two methods of optimization: cost-
based optimizer (CBO) and rule-based optimizer (RBO).
Query Optimizer
A SQL statement can be executed in many different ways, such as full table scans, index scans,
nested loops, and hash joins. The query optimizer determines the most efficient way to execute a
SQL statement after considering many factors related to the objects referenced and the conditions
specified in the query. This determination is an important step in the processing of any SQL
statement and can greatly affect execution time. The optimizer might not make the same decisions
from one version of Oracle to the next. In recent versions, the optimizer might make different
decisions, because better information is available.
Optimizer Operations
The output from the optimizer component is a plan (Execution Plan) that describes an optimum
method of execution. For any SQL statement processed by Oracle, the optimizer performs the
operations listed as follows:
Operation Description
Page 47
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Operation Description
Choice of access paths For each table accessed by the statement, the optimizer chooses one or
more of the available access paths to obtain table data.
Choice of join orders For a join statement that joins more than two tables, the optimizer
chooses which pair of tables is joined first, and then which table is joined
to the result, and so on.
Available Optimizers
Oracle has two modes for Optimizer to decide on the best execution plan, Rule based and Cost
based.
When more than one table is accessed in a query, the optimizer needs to decide which should be
the driving table. The RBO generates a set of join orders, each with a different table as the first
table. Then the most optimal plan is chosen from the resulting set of execution plans.
The optimizer evaluates the execution plans for various conditions such as (fewest nested-loop,
fewest sort-merge joins, table with the best ranking access path, etc.). If there is still a tie, the
optimizer chooses the execution plan for which the first table appears later in the query's FROM
clause. Hence, it is a conventional coding practice to put the driving table at the extreme right,
followed by other tables in order of access in the FROM clause, i.e., the ordering of tables based
on their access is from right to left.
Page 48
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Please note that the operators being used for searching the columns also play a role in deciding
the ranking. Sometimes even the age of an index is considered for ranking!
RBO was the preferred choice for most setups in earlier releases of oracle as the execution paths
were consistent and uniform. Queries would behave the same way if run on different databases of
the same application.
CBO uses all available information-statistics and histograms stored in the dictionary, user provided
hints and supplied parameter settings to arrive at the cost. CBO generates all possible
permutations of access methods and then chooses what fits best. The number of permutations
depends on the number of tables present in the query and can sometimes be around 80,000
permutations or even more!
CBO may also perform operations such as query transformation, view merging, OR
transformation, push join predicates, etc. that would change the original statement and alter
existing or add new predicates, all with the aim of deriving new access plans that could be better
than the existing ones. Note that transformation does not affect the data that is returned, only the
execution path.
Page 49
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
As per a published Oracle note, the existence of RBO prevents Oracle from making key
enhancements to its query-processing engine. Its removal will permit Oracle to improve
performance and reliability of the query-processing components of the database engine.
The Rule Based Optimizer (RBO) is now obsolete in Oracle 10g. The functionality is still present
but no new functionality has been included in it and it is no longer supported by Oracle. It is only
present to provide backwards compatibility during the migration to the query optimizer (Cost Based
Optimizer).
Optimizer Goal
By default, the goal of the query optimizer is the best throughput. This means that it chooses the
least amount of resources necessary to process all rows accessed by the statement. Oracle can
also optimize a statement with the goal of best response time. This means that it uses the least
amount of resources necessary to process the first row accessed by a SQL statement.
Choose a goal for the optimizer based on the needs of your application:
For applications performed in batch, such as Oracle Reports applications, optimize for
best throughput. Usually, throughput is more important in batch applications, because
the user initiating the application is only concerned with the time necessary for the
application to complete. Response time is less important, because the user does not
examine the results of individual statements while the application is running.
For interactive applications, such as Oracle Forms applications or SQL*Plus queries,
optimize for best response time. Usually, response time is important in interactive
applications, because the interactive user is waiting to see the first row or first few
rows accessed by the statement.
Page 50
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Transforming Queries
The input to the query transformer is a parsed query, which is represented by a set of query
blocks. The query blocks are nested or interrelated to each other. The form of the query
determines how the query blocks are interrelated to each other. The main objective of the query
transformer is to determine if it is advantageous to change the form of the query so that it enables
generation of a better query plan. Several different query transformation techniques are employed
by the query transformer, including:
View Merging: The simplest form of query transformation is view merging. For queries containing
views, the reference to the view can often be removed entirely from the query by ‘merging’ the
view definition with the query.
CREATE VIEW TEST_VIEW AS
SELECT ENAME, DNAME, SAL FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO;
SELECT ENAME, DNAME FROM TEST_VIEW WHERE SAL > 10000;
Without any query transformations, the only way to process this query is to join all of the rows of
EMP to all of the rows of the DEPT table, and then filter the rows with the appropriate values for
SAL.
Predicate Pushing: A complex query may contain multiple views and subqueries, with many
predicates that are applied to these views and subqueries. Oracle can move predicates into and
out of views in order to generate new, better performing queries.
Page 51
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Oracle will ‘push’ the predicate DEPTNO=10 into the view, and transform the query into the
following SQL:
SELECT DEPTNO, AVG(SAL)5 FROM EMP WHERE DEPTNO = 10
GROUP BY DEPTNO;
The advantage of this transformed query is that the DEPTNO=10 predicate is applied before the
GROUP-BY operation, and this could vastly reduce the amount of data to be aggregated.
Subquery Unnesting: Oracle has a variety of transformations that convert various types of
subqueries into joins, semi-joins, or anti-joins. As an example of the techniques in this area,
consider the following query, which selects those departments that have employees that make
more than 10000:
SELECT D.DNAME FROM DEPT D WHERE D.DEPTNO IN
(SELECT E.DEPTNO FROM EMP E WHERE E.SAL > 10000)
There are a variety of possible execution plans that could be optimal for this query. Oracle will
consider the different possible transformations, and select the best plan based on cost.
Without any transformations, the execution plan for this query would be similar to:
With this execution plan, the all of the EMP records satisfying the subquery’s conditions will be
scanned for every single row in the DEPT table. In general, this is not an efficient execution
strategy. However, query transformations can enable much more efficient plans.
The optimizer could determine that the DEPT table should be the inner table of the join. In that
case, it will execute the query as a regular join, but perform a unique sort of the EMP table in order
to eliminate duplicate department numbers:
Page 52
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Query Rewrite with Materialized Views: Pre-computing and storing commonly-used data in the
form of a materialized view can greatly speed up query processing. Oracle can transform SQL
queries so that one or more tables referenced in a query can be replaced by a reference to a
materialized view. If the materialized view is smaller than the original table or tables, or has better
available access paths, the transformed SQL statement could be executed much faster than the
original one.
Oracle has a very robust set of rewrite techniques for materialized views, in order to allow each
materialized view to be used for as broad a set of queries as possible.
OR-expansion: This technique converts a query with ORs in the WHERE-clause into a UNION
ALL of several queries without ORs. It can be highly beneficial when the Ors refer to restrictions of
different tables. Consider the following query to find all the shipments that went either from or to
Oakland.
SELECT * FROM SHIPMENT, PORT P1, PORT P2
WHERE SHIPMENT.SOURCE_PORT_ID = P1.PORT_ID
AND SHIPMENT.DESTINATION_PORT_ID = P2.PORT_ID
AND (P1.PORT_NAME = 'OAKLAND' OR P2.PORT_NAME = 'OAKLAND')
Page 53
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Note that each UNION ALL branch can have different optimal join orders. In the first branch,
Oracle could take advantage of the restriction on P1 and drive the join from that table. In the
second branch, Oracle could drive from P2 instead.
Any combination of these transformations can be applied to a given query.
Estimating
The estimator generates three different types of measures:
Selectivity
Cardinality
Cost
These measures are related to each other, and one is derived from another. The end goal of the
estimator is to estimate the overall cost of a given plan. If statistics are available, then the
estimator uses them to compute the measures. The statistics improve the degree of accuracy of
the measures.
Selectivity: Selectivity represents a fraction of rows from a row set. The row set can
be a base table, a view, or the result of a join or a GROUP BY operator. The selectivity
is tied to a query predicate, such as last_name = 'Smith', or a combination of
predicates, such as last_name = 'Smith' AND job_type = 'Clerk'. A predicate acts as a
filter that filters a certain number of rows from a row set. Therefore, the selectivity of a
predicate indicates how many rows from a row set will pass the predicate test.
Selectivity lies in a value range from 0.0 to 1.0. A selectivity of 0.0 means that no rows
will be selected from a row set, and a selectivity of 1.0 means that all rows will be
selected.
Cardinality: Cardinality represents the number of rows in a row set. Here, the row set
can be a base table, a view, or the result of a join or GROUP BY operator.
Cost: The cost represents units of work or resource used. The query optimizer uses
disk I/O, CPU usage, and memory usage as units of work. So, the cost used by the
query optimizer represents an estimate of the number of disk I/Os and the amount of
CPU and memory used in performing an operation.
The access path determines the number of units of work required to get data from a base table.
The access path can be a table scan, a fast full index scan, or an index scan. During table scan or
fast full index scan, multiple blocks are read from the disk in a single I/O operation. Therefore, the
cost of a table scan or a fast full index scan depends on the number of blocks to be scanned and
the multi-block read count value.
Page 54
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
The join cost represents the combination of the individual access costs of the two row sets being
joined, plus the cost of the join operation.
Generating Plans
The main function of the plan generator is to try out different possible plans for a given query and
pick the one that has the lowest cost. Many different plans are possible because of the various
combinations of different access paths, join methods, and join orders that can be used to access
and process data in different ways and produce the same result.
Explain Plan
Whenever you read or write data in Oracle, you do so by issuing an SQL statement. One of
Oracle's tasks when it receives such a statement is to build a query execution plan. An execution
plan defines how Oracle finds or writes the data. For example, an important decision that Oracle
has to take is if it uses indexes or not. And if there are more indexes, which of these is used. All
this is contained in an execution plan.
If one wants to explore such an execution plan, Oracle provides the SQL statement EXPLAIN
PLAN to determine this
EXPLAIN PLAN
INTO my_plan_table
SET STATEMENT_ID = 'bad1' FOR
SELECT name FROM emp;
If you do an EXPLAIN PLAN, then Oracle will analyze the statement and fill in the results into Plan
table. Plan table will hold the execution plan for a SQL statement. The most important fields
within the plan table are operation, option, object_name, id, and parent_id.
Page 55
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Plan
---------------------------------------------
SELECT STATEMENT
TABLE ACCESS FULL PER_ALL_PEOPLE_F
This plan shows execution of a SELECT statement. The table PER_ALL_PEOPLE_F is accessed
using a full table scan.
Every row in the table PER_ALL_PEOPLE_F is accessed, and the WHERE clause
criteria is evaluated for every row.
The SELECT statement returns the rows meeting the WHERE clause criteria.
Even though there is index in table PER_ALL_PEOPLE_F it is not used because a
function is used in the column in where criteria.
Plan
---------------------------------------------
SELECT STATEMENT
TABLE ACCESS BY INDEX ROWID PER_ALL_PEOPLE_F
INDEX RANGE SCAN PER_PEOPLE_F_N54
Minimizing Throw-Away
Examining an explain plan lets you look for throw-away in cases such as the following:
Full scans
Unselective range scans
Late predicate filters
Page 56
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
For example, in the following explain plan, the last step is a very unselective range scan that is
executed 76563 times, accesses 11432983 rows, throws away 99% of them, and retains 76563
rows. Why access 11432983 rows to realize that only 76563 rows are needed?
12 SORT AGGREGATE
2 SORT GROUP BY
76563 NESTED LOOPS
76575 NESTED LOOPS
19 TABLE ACCESS FULL CN_PAYRUNS_ALL
76570 TABLE ACCESS BY INDEX ROWID CN_POSTING_DETAILS_ALL
76570 INDEX RANGE SCAN (object id 178321)
76563 TABLE ACCESS BY INDEX ROWID CN_PAYMENT_WORKSHEETS_ALL
11432983 INDEX RANGE SCAN (object id 186024)
Optimizer Hints
Optimizer hints can be used with SQL statements to alter execution plans. Hints provide a
mechanism to instruct the optimizer to choose a certain query execution plan based on the specific
criteria.
For example, you might know that a certain index is more selective for certain queries.
Based on this information, you might be able to choose a more efficient execution plan
than the optimizer. In such a case, use hints to instruct the optimizer to use the optimal
execution plan.
Example 1: In the following example, including /*+ RULE */ inside the SELECT statement
instructs the optimizer to use the rule-based optimizer rather than the cost-based optimizer:
SELECT /*+ RULE */ . . . .
FROM emp, dept
WHERE . . .
Page 57
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Example 2: The hint in this case is FULL(dept); it tells Oracle to do a full table scan of the dept
table. Oracle will honor this hint and perform a full table scan of dept when joining the tables, even
if it appears that doing so will degrade performance
SELECT /*+ FULL(dept) */
empno, ename, dname
FROM emp, dept
WHERE emp.deptno = dept.deptno;
Example 3: Note that the table emp has an alias e. The hint for the table uses the same alias, and
is specified as FULL(e). Whenever an alias is used, the alias name must be used in any hints for
the table:
SELECT /*+ FULL(e) do a full tablescan on the emp table, because
most employees do have billing rates < 4000. */
empno, ename
FROM emp e
WHERE sal < 4000;
Example 4: When subqueries are used, they are allowed to have their own hints. The hint for a
subquery follows the keyword that starts the query, as shown in the following:
SELECT /*+ FIRST_ROWS */ empno, ename
FROM emp
WHERE NOT EXISTS (
SELECT /*+ FULL(dept) */ *
FROM dept
WHERE emp.deptno = dept.deptno
AND dept.loc IN ('NEW YORK', 'BOSTON', 'CHICAGO'));
Types of Hints
Oracle hints can be divided loosely into the following categories:
Optimizer goal hints
Access method hints
Join order hints
Join operation hints
Parallel execution hints
Other hints
Page 58
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Some access method hints are index-related and allow identification of indexes to be used. In
many cases, such as with the INDEX hint, the index name may or may not be specified.
The following hint tells Oracle to perform an index scan on the EMP table, but that it is up to Oracle
to pick the index:
/*+ INDEX(emp) */
Hint Description
FULL(table_name) Requests a full table scan of the specified table, regardless of any
indexes that may exist.
ROWID(table_name) Tells Oracle to perform a scan of the specified table based on
ROWIDs.
CLUSTER(table_name) Tells Oracle to do a cluster scan of the specified table. This hint is
ignored if the table is not clustered
HASH(table_name) Tells Oracle to perform a hash scan of the specified table. This hint
is ignored if the table is not clustered.
INDEX(table_name Tells Oracle to access the specified table via an index scan. You
[index_name...]) may specify which index to use; otherwise Oracle chooses the
index. You may also specify a list of indexes to choose from, and
Oracle will choose from that list.
Page 59
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Summary
Optimizer uses internal rules and available statistics to determine most efficient way of
producing result set of the query.
There are two types of optimizer like rule based optimizer (RBO) and cost based
optimizer (CBO).
Optimizer has the following components:
o Transforming Queries
o Estimating
o Generating Plans
Explain plan is a provision through which you can explore the execution plan selected
by optimizer.
Optimizer hints can be used with SQL statements to alter execution plans.
Page 60
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Page 61
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Learning Objectives
After the completing of this session, you would be able to:
List the reasons for the PL/SQL performance issues
Identify the PL/SQL performance issues
List PL/SQL features for performance tuning
State the standards and best practices in PL/SQL
When to Tune
Over time, even the performance of well-designed applications can degrade. So, periodic tuning is
an important part of application maintenance. You can make small adjustments that can drastically
improve performance. Consider tuning your PL/SQL code in the following scenarios:
Programs that do a lot of mathematical calculations. You will want to investigate
the data types PLS_INTEGER, BINARY_FLOAT, and BINARY_DOUBLE.
Functions that are called from PL/SQL queries, where the functions might be
executed millions of times. You will want to look at all performance features to make
the function as efficient as possible, and perhaps a function-based index to
precompute the results for each row and save on query time.
Programs that spend a lot of time processing INSERT, UPDATE, or DELETE
statements, or looping through query results. You will want to investigate the FORALL
statement for issuing DML, and the BULK COLLECT INTO and RETURNING BULK
COLLECT INTO clauses for queries.
Older code that does not take advantage of recent PL/SQL language features.
With the many performance improvements in Oracle Database 10g, any code from
earlier releases is a candidate for tuning.
Any program that spends a lot of time doing PL/SQL processing, as opposed to
issuing DDL statements like CREATE TABLE that are just passed directly to SQL. You
will want to investigate native compilation. Because many built-in database features
use PL/SQL, you can apply this tuning feature to an entire database to improve
performance in many areas, not just your own code.
Before starting any tuning effort, benchmark the current system and measure how long particular
subprograms take. PL/SQL performance tuning can be achieved by following aspects.
1. Understanding the reasons for PL/SQL Performance Problems
2. Identifying PL/SQL Performance Problems
3. PL/SQL Features for Performance Tuning
Page 62
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
No matter how suitable a programming language is for a given task, badly written subprograms
(for example, a slow sort or search function) can ruin performance. Suppose the subprogram
called most often by an application is a lookup function with hundreds of possible targets. If that
function could be written as a hash or a binary search but, instead, is written as a linear search,
overall performance suffers.
Other poor practices include declaring variables that are never used, passing unneeded
parameters to functions and procedures, placing initializations or computations inside a loop
needlessly, and so on.
Page 63
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
The Boolean function credit_ok is always called. However, if you switch the operands of AND
as follows
IF (loan < 5000) AND credit_ok(customer_id) THEN
...
END IF;
The function is called only when the expression loan < 5000 is true (because AND returns TRUE
only if both its operands are true). The same idea applies to EXIT-WHEN statements.
Avoiding implicit conversions can improve performance. Look at the example below. The integer
literal 15 is represented internally as a signed 4-byte quantity, so PL/SQL must convert it to an
Oracle number before the addition. However, the floating-point literal 15.0 is represented as a 22-
byte Oracle number, so no conversion is necessary.
DECLARE
Count NUMBER;
BEGIN
Count := Count + 15; -- converted
Count := Count + 15.0; -- not converted
...
END;
Page 64
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Page 65
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Subsequent calls to related subprograms in the package require no disk I/O, and your code
executes faster. However, if the package is aged out of memory, it must be reloaded if you
reference it again. You can improve performance by sizing the shared memory pool correctly.
Make sure it is large enough to hold all frequently used packages but not so large that memory is
wasted.
To use the Profiler, you start the profiling session, run your application long enough to get
adequate code coverage; flush the collected data to the database, then stop the profiling session.
In a typical session, you take the following steps:
1. Start by calling the procedure start_profiler in package DBMS_PROFILER and
associating a comment with the Profiler session.
2. Run the application to be profiled.
3. Call the procedure flush_data repeatedly to save incremental data and free memory
allocated for data structures.
4. Stop by calling the procedure stop_profiler.
Page 66
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
The Profiler traces the execution of your program, computing the time spent at each line and in
each subprogram. You can use the collected data to improve performance. For instance, you
might focus on subprograms that run slowly.
Using Profiler
The first step is to install the DBMS_PROFILER package:
CONNECT sys/password@service AS SYSDBA
@$ORACLE_HOME/rdbms/admin/profload.sql
CONNECT profiler/profiler@service
@$ORACLE_HOME/rdbms/admin/proftab.sql
GRANT SELECT ON plsql_profiler_runnumber TO PUBLIC;
GRANT SELECT, INSERT, UPDATE, DELETE ON plsql_profiler_data TO PUBLIC;
GRANT SELECT, INSERT, UPDATE, DELETE ON plsql_profiler_units TO PUBLIC;
GRANT SELECT, INSERT, UPDATE, DELETE ON plsql_profiler_runs TO PUBLIC;
Page 67
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Next you start the profiler, run our procedure and stop the profiler:
DECLARE
l_result BINARY_INTEGER;
BEGIN
l_result := DBMS_PROFILER.start_profiler(run_comment => 'do_something:
' || SYSDATE);
do_something(p_times => 100);
l_result := DBMS_PROFILER.stop_profiler;
END;
/
With the profile complete you can analyze the data to see which bits of the process took the most
time, with all times presented in nanoseconds. First you check out which runs you have:
SET LINESIZE 200
SET TRIMOUT ON
Page 68
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
You can then use the appropriate RUNID value in the following query:
COLUMN runid FORMAT 99999
COLUMN unit_number FORMAT 99999
COLUMN unit_type FORMAT A20
COLUMN unit_owner FORMAT A20
SELECT u.runid,
u.unit_number,
u.unit_type,
u.unit_owner,
u.unit_name,
d.line#,
d.total_occur,
d.total_time,
d.min_time,
d.max_time
FROM plsql_profiler_units u
JOIN plsql_profiler_data d ON u.runid = d.runid AND u.unit_number
= d.unit_number
WHERE u.runid = 1
ORDER BY u.unit_number, d.line#;
RUNID UNIT_NU UNIT_TYPE UNIT_OWNER UNIT_NAME LINE# TOTAL_OCCUR TOTAL_TIME MIN_TIME MAX_TIME
----- ------- --------------- ----------- ------------ ----- ----------- ---------- -------- --------
5 rows selected.
The results of this query show that line 4 of the DO_SOMETHING procedure ran 101 times but took
very little time, while line 5 ran 100 times and took proportionately more time. You can check the
line numbers of the source using the following query:
SELECT line || ' : ' || text
FROM all_source
WHERE owner = 'MY_SCHEMA'
AND type = 'PROCEDURE'
AND name = 'DO_SOMETHING';
LINE||':'||TEXT
---------------------------------------------------
1 : PROCEDURE do_something (p_times IN NUMBER) AS
Page 69
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
2 : l_dummy NUMBER;
3 : BEGIN
4 : FOR i IN 1 .. p_times LOOP
5 : SELECT l_dummy + 1
6 : INTO l_dummy
7 : FROM dual;
8 : END LOOP;
9 : END;
As expected, the query took proportionately more time than the procedural loop
To use Trace, you start the tracing session, run your application, then stop the tracing session. As
the program executes, trace data is collected and stored in database tables. In a typical session,
you take the following steps:
1. Optionally, select specific subprograms for trace data collection.
2. Start by calling the procedure set_plsql_trace in package DBMS_TRACE.
3. Run the application to be traced.
4. Stop by calling the procedure clear_plsql_trace.
In addition, you can choose a tracing level. For example, you can choose to trace all subprograms
and exceptions, or you can choose to trace selected subprograms and exceptions.
Using DBMS_Trace
The first step is to install the tables which will hold the trace data:
CONNECT sys/password@service AS SYSDBA
@$ORACLE_HOME/rdbms/admin/tracetab.sql
Page 70
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Next you run your procedure three times with different tracing levels:
DECLARE
l_result BINARY_INTEGER;
BEGIN
DBMS_TRACE.set_plsql_trace (DBMS_TRACE.trace_all_calls);
do_something(p_times => 100);
DBMS_TRACE.clear_plsql_trace;
DBMS_TRACE.set_plsql_trace (DBMS_TRACE.trace_all_sql);
do_something(p_times => 100);
DBMS_TRACE.clear_plsql_trace;
DBMS_TRACE.set_plsql_trace (DBMS_TRACE.trace_all_lines);
do_something(p_times => 100);
DBMS_TRACE.clear_plsql_trace;
END;
/
With the tracing complete you can identify the available RUNIDs using the following query:
SELECT r.runid,
TO_CHAR(r.run_date, 'DD-MON-YYYY HH24:MI:SS') AS run_date,
r.run_owner
FROM plsql_trace_runs r
ORDER BY r.runid;
Page 71
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
You can then use the appropriate RUNID in the following query to look at the trace:
SET LINESIZE 200
SET TRIMOUT ON
SELECT e.runid,
e.event_seq,
TO_CHAR(e.event_time, 'DD-MON-YYYY HH24:MI:SS') AS event_time,
e.event_unit_owner,
e.event_unit,
e.event_unit_kind,
e.proc_line,
e.event_comment
FROM plsql_trace_events e
WHERE e.runid = 1
ORDER BY e.runid, e.event_seq
Page 72
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Dynamic SQL statements are stored in character strings built by your program at run time. Such
strings must contain the text of a valid SQL statement or PL/SQL block. They can also contain
placeholders for bind arguments. A placeholder is an undeclared identifier, so its name, to which
you must prefix a colon, does not matter.
For improving the performance see the example below, Oracle opens a different cursor for each
distinct value of emp_id. This can lead to resource contention and poor performance.
CREATE PROCEDURE fire_employee (emp_id NUMBER) AS
BEGIN
EXECUTE IMMEDIATE
'DELETE FROM emp WHERE empno = ' || TO_CHAR(emp_id);
END;
You can improve performance by using a bind variable, as shown below. This allows Oracle to
reuse the same cursor for different values of emp_id.
CREATE PROCEDURE fire_employee (emp_id NUMBER) AS
BEGIN
EXECUTE IMMEDIATE
'DELETE FROM emp WHERE empno = :num' USING emp_id;
END;
Page 73
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
...
FOR i IN depts.FIRST..depts.LAST LOOP
...
UPDATE emp SET salary = salary * 1.10 WHERE deptno = depts(i);
END LOOP;
END;
In such cases, if the SQL statement affects four or more database rows, the use of bulk binds can
improve performance considerably. For example, the following UPDATE statement is sent to the
SQL engine just once, with the entire nested table:
FORALL i IN depts.FIRST..depts.LAST
UPDATE emp SET salary = salary * 1.10 WHERE deptno = depts(i);
If the SQL statement affects four or more database rows, the use of bulk binds can improve
performance considerably.
A DML statement can transfer all the elements of a collection in a single operation, a process
known as bulk binding. If the collection has 20 elements, bulk binding lets you perform the
equivalent of 20 SELECT, INSERT, UPDATE, or DELETE statements using a single operation. This
technique improves performance by minimizing the number of context switches between the
PL/SQL and SQL engines. With bulk binds, entire collections, not just individual elements, are
passed back and forth.
To do bulk binds with INSERT, UPDATE, and DELETE statements, you enclose the SQL statement
within a PL/SQL FORALL statement. To do bulk binds with SELECT statements, you include the
BULK COLLECT clause in the SELECT statement instead of using INTO.
Page 74
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
When the parameters hold large data structures such as collections, records, and instances of
object types, all this copying slows down execution and uses up memory. To prevent that, you can
specify the NOCOPY hint, which allows the PL/SQL compiler to pass OUT and IN OUT parameters
by reference. In the following example, you ask the compiler to pass IN OUT parameter my_unit
by reference instead of by value:
DECLARE
TYPE Platoon IS VARRAY(200) OF Soldier;
PROCEDURE reorganize (my_unit IN OUT NOCOPY Platoon) IS ...
BEGIN
...
END;
In the following example, you update the salary of an employee and at the same time retrieve the
employee's name and new salary into PL/SQL variables.
PROCEDURE update_salary (emp_id NUMBER) IS
name VARCHAR2(15);
new_sal NUMBER;
BEGIN
UPDATE emp SET sal = sal * 1.1
WHERE empno = emp_id
RETURNING ename, sal INTO name, new_sal;
-- Now do computations involving name and new_sal
END;
Page 75
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Collection: A collection is an ordered group of elements, all of the same type. It is a general
concept that encompasses lists, arrays, and other familiar data types. PL / SQL offer the following
collection type
Associate Arrays (index- by tables)
Nested Tables
Varrays
Varrays Example:
In SQL*Plus, suppose you define object type Project, as follows:
SQL> CREATE TYPE Project AS OBJECT (
2 project_no NUMBER(2),
3 title VARCHAR2(35),
4 cost NUMBER(7,2));
Next, you define VARRAY type ProjectList, which stores Project objects:
SQL> CREATE TYPE ProjectList AS VARRAY(50) OF Project;
Finally, you create relational table department, which has a column of type ProjectList, as
follows:
SQL> CREATE TABLE department (
2 dept_id NUMBER(2),
3 name VARCHAR2(15),
4 budget NUMBER(11,2),
5 projects ProjectList);
Each item in column projects is a varray that will store the projects scheduled for a given
department.
Now, you are ready to populate relational table department. In the following example, notice how
varray constructor ProjectList() provides values for column projects:
BEGIN
INSERT INTO department
VALUES(30, 'Accounting', 1205700,
ProjectList(Project(1, 'Design New Expense Report', 3250),
Project(2, 'Outsource Payroll', 12350),
Project(3, 'Evaluate Merger Proposal', 2750),
Project(4, 'Audit Accounts Payable', 1425)));
INSERT INTO department
VALUES(50, 'Maintenance', 925300,
ProjectList(Project(1, 'Repair Leak in Roof', 2850),
Project(2, 'Install New Door Locks', 1700),
Project(3, 'Wash Front Windows', 975),
Project(4, 'Repair Faulty Wiring', 1350),
Project(5, 'Winterize Cooling System', 1125)));
INSERT INTO department
Page 76
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
In the following example, you update the list of projects assigned to the Security Department:
DECLARE
new_projects ProjectList :=
ProjectList(Project(1, 'Issue New Employee Badges', 13500),
Project(2, 'Develop New Patrol Plan', 1250),
Project(3, 'Inspect Emergency Exits', 1900),
Project(4, 'Upgrade Alarm System', 3350),
Project(5, 'Analyze Local Crime Stats', 825));
BEGIN
UPDATE department
SET projects = new_projects WHERE dept_id = 60;
END;
In the next example, you retrieve all the projects for the Accounting Department into a local varray:
DECLARE
my_projects ProjectList;
BEGIN
SELECT projects INTO my_projects FROM department
WHERE dept_id = 30;
END;
In the final example, you delete the Accounting Department and its project list from table
department:
BEGIN
DELETE FROM department WHERE dept_id = 30;
END;
In the following example, stored procedure ADD_PROJECT inserts a new project into a
department's project list at a given position:
CREATE PROCEDURE add_project (
dept_no IN NUMBER,
new_project IN Project,
Page 77
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
position IN NUMBER) AS
my_projects ProjectList;
BEGIN
SELECT projects INTO my_projects FROM department
WHERE dept_no = dept_id FOR UPDATE OF projects;
my_projects.EXTEND; -- make room for new project
/* Move varray elements forward. */
FOR i IN REVERSE position..my_projects.LAST - 1 LOOP
my_projects(i + 1) := my_projects(i);
END LOOP;
my_projects(position) := new_project; -- add new project
UPDATE department SET projects = my_projects
WHERE dept_no = dept_id;
END add_project;
Now the PL/SQL optimizing compiler will transform the query to a better performing query based
on the transformation rules defined. PLSQL optimizing compiler will behave similar to SQL
compiler. To enable the PLSQL optimizing compiler to give you better performances you need to
assign the following value to the initialization parameter “plsql_optimization_level“ . Following are
the possible values and related behaviors.
2: Most aggressive, maximum possible code transformations, biggest impact on
compile time while compiling large applications.
1: Smaller scale change, less impact on compile times.
0: Pre-10g compilation without any optimization
Use the following statement to alter the plsql_optimization_level parameter for a session.
Alter session set PLSQL_OPTIMIZE_LEVEL=0;
Page 78
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
LOOP
DBMS_OUTPUT.PUT_LINE(item.col_alias);
END LOOP;
-- Efficient, only calls function once for each distinct value.
FOR item IN
( SELECT SQRT(department_id) col_alias FROM
( SELECT DISTINCT department_id FROM employees)
)
LOOP
DBMS_OUTPUT.PUT_LINE(item.col_alias);
END LOOP;
END;
In the following example PLSQL engine sends the all three delete statements to SQL engine at
once.
CREATE TABLE employees_temp AS SELECT * FROM employees;
DECLARE
TYPE NumList IS VARRAY(20) OF NUMBER;
depts NumList := NumList(10, 30, 70); -- department numbers
BEGIN
FORALL i IN depts.FIRST..depts.LAST
DELETE FROM employees_temp WHERE department_id = depts(i);
COMMIT;
END;
Use FORALL and BULK COLLECT together: Bulk collect clause can be used along with FORALL
statement to increase the performance.
CREATE TABLE emp_temp AS SELECT * FROM employees;
DECLARE
TYPE NumList IS TABLE OF NUMBER;
depts NumList := NumList(10,20,30);
TYPE enum_t IS TABLE OF employees.employee_id%TYPE;
Page 79
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Developers and support personnel alike are faced, quite often, with a situation where the
definitions of the tables have to be altered from one data type to another. In an ideal world nothing
else would need modification. Realistically, this can break all the PL/SQL code that is based on
this table. Modifying all this code can be a daunting task. Using anchored declarations can bring
our ideal world a step closer to us.
Page 80
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Wherever possible use anchored declarations rather than explicit data type references as given
below.
Also, suppose there is a stored procedure that prints out an alert message when the quantity of an
item in stock falls below a certain limit.
CREATE OR REPLACE PROCEDURE inventory_update (item_id_in IN NUMBER) IS
v_qty NUMBER;
BEGIN
SELECT qty into v_qty FROM items WHERE item_id = item_id_in;
Doing this will cause the code to have the same data type as that of the column in the table. Your
code will work without any modification.
Page 81
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
a shared memory area so that when the same statement is issued again by the program, the
system can skip the parsing step, thus saving processing time and resources.
The following code is given for the purpose of demonstration and comparison only and may not
reflect real-life situation.
DECLARE
BEGIN
FOR i IN 1 .. 1000 LOOP
EXECUTE IMMEDIATE
'SELECT item_id, qty FROM items WHERE qty = ' || i;
END LOOP;
END;
Every iteration of the loop produces the following statements:
SELECT item_id, qty FROM items WHERE qty = 1;
SELECT item_id, qty FROM items WHERE qty = 2;
SELECT item_id, qty FROM items WHERE qty = 3;
and so on.
When the system checks the shared memory area (shared pool) it considers each statement to be
unique and fails to make use of the parsed information already available. You, however, know that
the statements are almost identical. Bind variables can help remedy this situation. Consider the
following code:
DECLARE
BEGIN
FOR i IN 1 .. 1000 LOOP
EXECUTE IMMEDIATE
'SELECT item_id, qty FROM items WHERE qty = :x' using i;
END LOOP;
END;
In this case the parser will get exactly the same information in every loop iteration and would not
have to re-parse the SQL statement.
Not only that the code is faster with the use of the bind variables, it is also less CPU intensive and
allows better sharing of resources by decreasing the number of latches resulting in not just better
performing code but a better performing system as a whole.
As is evident from the code examples above, bind variables are applicable in situations where
dynamic SQL is being used. Since today's graphical user interface programming makes very
heavy use of dynamic SQL, there are more opportunities of realizing the advantage of bind
variables.
Page 82
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
By using bulk collects, you can load multiple rows into the collections rather than one at a time
thus reducing strain on database resources by reducing the pass to the database.
CREATE OR replace PROCEDURE no_bulk_proc is
CURSOR item_cur IS
SELECT items.item_id, qty FROM items;
item_rec item_cur%ROWTYPE;
BEGIN
OPEN item_cur;
LOOP
FETCH item_cur INTO item_rec;
EXIT WHEN item_cur%notfound;
dbms_output.put_line(item_rec.item_id);
dbms_output.put_line(item_rec.qty);
END LOOP;
END no_bulk_proc;
Without using BULK collects
v_item t_item;
v_qty t_qty;
BEGIN
OPEN item_cur;
FETCH item_cur bulk collect INTO v_item, v_qty limit 100;
CLOSE item_cur;
END bulk_proc;
Using BULK collects
Here the 'limit 100' loads only 100 records into memory for processing which provides an added
benefit that you have reduced the risk of running out of main memory as opposed to the code in
figure which may run into memory issues.
Write SQL Efficiently in PL/SQL Programs
Page 83
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
When you write SQL statements inside PL/SQL programs make sure it is more efficient and it does
not use hard parsing when you call it repeatedly with different values. For example when you want
to delete the employee records from a table based on the passed value. Make sure the emp_id
which is supplied in the where criteria of the delete statement is passed through a bind variable
rather than using a local variable and assigning to it. Other tips for writing efficient SQL Statements
in PL/SQL is given as follows
Use native SQL whenever possible: Find below the comparison between the native
SQL and the dynamic SQL. When native SQL is used the code become dramatically
less at the same time it increases the performance also
.
Dynamic SQL Native SQL
CREATE OR REPLACE PROCEDURE CREATE OR REPLACE PROCEDURE
showemps ( showemps (
where_in IN VARCHAR2 := NULL) where_in IN VARCHAR2 := NULL)
IS IS
cur INTEGER := TYPE cv_typ IS REF CURSOR;
DBMS_SQL.OPEN_CURSOR; cv cv_typ;
rec employee%ROWTYPE; v_id employee.employee_id%TYPE;
fdbk INTEGER; v_nm employee.last_name%TYPE;
BEGIN BEGIN
DBMS_SQL.PARSE OPEN cv FOR
(cur, 'SELECT employee_id,
'SELECT employee_id, last_name
last_name FROM employee
FROM employee WHERE ' || NVL (where_in,
WHERE ' || NVL (where_in, '1=1');
'1=1'), LOOP
DBMS_SQL.NATIVE); FETCH cv INTO v_id, v_nm;
EXIT WHEN cv%NOTFOUND;
DBMS_SQL.DEFINE_COLUMN (cur, 1, DBMS_OUTPUT.PUT_LINE (
1); TO_CHAR (v_id) || '=' ||
DBMS_SQL.DEFINE_COLUMN (cur, 2, v_nm);
user, 30); END LOOP;
CLOSE cv;
fdbk := DBMS_SQL.EXECUTE (cur); END;
LOOP
/* Fetch next row. Exit when
done. */
EXIT WHEN DBMS_SQL.FETCH_ROWS
(cur) = 0;
DBMS_SQL.COLUMN_VALUE (cur,
1, rec.employee_id);
DBMS_SQL.COLUMN_VALUE (cur,
2, rec.last_name);
DBMS_OUTPUT.PUT_LINE (
TO_CHAR (rec.employee_id)
Page 84
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Use PL/SQL to replace IO-intensive SQL. Make use of PL/SQL to avoid intensive /
big SQL statements An example of this is given as follows:
Use the RETURNING Clause: Use Returning clause to collect the recently updated/
deleted values that is processed by a statement. An example is given below for better
understanding.
Use WHERE CURRENT OF: When using SELECT FOR UPDATE, use the WHERE
CURRENT OF clause in UPDATE and DELETE to avoid coding a possibly complex and
slower WHERE clause.
Page 85
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Never put the variable and other data structures in package specification:
Mostly try to have the variables and bulky data structures in the package body instead
of the package specifications
Avoid Multiple returns in the functions: Multiple RETURNs in the executable section
make it error-prone and difficult to maintain.
Page 86
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Without a doubt, if you can follow these guidelines, you are sure to end up with programs which
are easier to maintain and enhance:
Never exit from a FOR loop (numeric or cursor) with an EXIT or RETURN statement. A
FOR loop is a promise: my code will iterate from the starting to the ending value and
will then stop execution.
Never exit from a WHILE loop with an EXIT or RETURN statement. Rely solely on the
WHILE loop condition to terminate the loop.
Ensure that a function has a single successful RETURN statement as the last line of the
executable section. Normally, each exception handler in a function would also return a
value.
Don't let functions have OUT or IN OUT parameters. The function should only return
values through the RETURN clause.
Make sure that the name of a function describes the value being returned (noun
structure, as in "total_compensation"). The name of a procedure should describe
the actions taken (verb-noun structure, as in "calculate_totals").
Never declare the FOR loop index (either an integer or a record). This is done for you
implicitly by the PL/SQL runtime engine.
Do not use exceptions to perform branching logic. When you define your own
exceptions, these should describe error situations only.
When you use the ELSIF statement, make sure that each of the clauses is mutually
exclusive. Watch out especially for logic like "sal BETWEEN 1 and 10000" and
"sal BETWEEN 10000 and 20000."
Remove all hardcoded "magic values" from your programs and replace them with
named constants or functions defined in packages.
Do not "SELECT COUNT(*)" from a table unless you really need to know the total
number of "hits." If you only need to know whether there is more than one match,
simply fetch twice with an explicit cursor.
Do not use the names of tables or columns for variable names. This can cause
compile errors. It can also result in unpredictable behavior inside SQL statements in
your PL/SQL code. Once did a global search and replace of :GLOBAL.regcd to
regcd (a local variable declared as VARCHAR2(10) but also, unfortunately, the name
of a column). Our Q&A procedures were very weak and we ended up rolling out into
production a program with a DELETE statement containing a WHERE clause that looked
like this:
WHERE regcd = regcd
Needless to say, this caused many headaches. If you had simply changed the global reference to
v_regcd, you would have avoided all such problems.
Page 87
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Summary
Following are the reasons for PL/SQL performance problems:
o Badly written SQL statements
o Poor programming practices
o Not using the build-in features present in Oracle
o Inefficient conditional control statements
Some poor programming practices are as follows:
o Declaring variables that are never used
o Passing unneeded parameters to functions and procedures
o PL/SQL provides a profiler API to profile run-time behavior to find the performance
barriers.
PL/SQL provides a profiler API to profile run-time behavior to find the performance
barriers.
Page 88
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Learning Objectives
After completing this session, you will be able to:
Explain the Execute Plan
Generate Explain Plan
Explain SQL Trace
Identify TKPROF utilities
State the steps in using SQL Trace and TKPROF utility
Describe the TKPROF results
Explain Plan
The EXPLAIN PLAN is a statement used for displaying the execution plans chosen by the Oracle
optimizer for SELECT, UPDATE, INSERT, and DELETE statements. A statement's execution plan is
the sequence of operations Oracle performs to run the statement. When an SQL statement is
passed to the server the Cost Based Optimizer (CBO) uses database statistics to create an
execution plan which it uses to navigate through the data. Once you've highlighted a problem
query the first thing you should do is EXPLAIN the statement to check the execution plan that the
CBO has created. This will often reveal that the query is not using the relevant indexes, or indexes
to support the query are missing.
The EXPLAIN PLAN statement allows you to submit a SQL statement to Oracle and have the
database prepare the execution plan for the statement without actually executing it. The execution
plan is made available to you in the form of rows inserted into a special table called a plan table.
You may query the rows in the plan table using ordinary SELECT statements in order to see the
steps of the execution plan for the statement you explained. You may keep multiple execution
plans in the plan table by assigning each a unique statement_id. Or you may choose to delete the
rows from the plan table after you are finished looking at the execution plan. You can also roll back
an EXPLAIN PLAN statement in order to remove the execution plan from the plan table.
The EXPLAIN PLAN statement runs very quickly, even if the statement being explained is a query
that might run for hours. This is because the statement is simply parsed and its execution plan
saved into the plan table. The actual statement is never executed by EXPLAIN PLAN. Along these
same lines, if the statement being explained includes bind variables, the variables never need to
actually be bound. The values that would be bound are not relevant since the statement is not
actually executed.
Page 89
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
You do not need any special system privileges in order to use the EXPLAIN PLAN statement.
However, you do need to have INSERT privileges on the plan table, and you must have sufficient
privileges to execute the statement you are trying to explain. The one difference is that in order to
explain a statement that involves views, you must have privileges on all of the tables that make up
the view. If you do not, you will get an “ORA-01039: insufficient privileges on underlying objects of
the view” error.
Different Schemas
The execution and explain plan happen on different databases.
The user explaining the statement is different from the user running the statement.
Two users might be pointing to different objects in the same database, resulting in
different execution plans.
Schema changes (usually changes in indexes) between the two operations.
Different Costs
Even if the schemas are the same, the optimizer can choose different execution plans if the costs
are different. Some factors that affect the costs include the following:
Data volume and statistics
Bind variable types and values
Initialization parameters: Set globally or at session level
Examining an explain plan lets you look for throw-away in cases such as the following:
Full scans
Unselective range scans
Late predicate filters
Wrong join order
Late filter operations
For example, in the following explain plan, the last step is a very unselective range scan that is
executed 76563 times, accesses 11432983 rows, throws away 99% of them, and retains 76563
rows. Why access 11432983 rows to realize that only 76563 rows are needed?
Page 90
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
If you do not specify the INTO clause, then Oracle assumes the name of the plan table is
plan_table. You can use the SET clause to assign a name to the execution plan. This is useful if
you want to be able to have multiple execution plans stored in the plan table at once giving each
execution plan a distinct name enables you to determine which rows in the plan table belong to
which execution plan.
The EXPLAIN PLAN statement runs quickly because all Oracle has to do is parse the SQL
statement being explained and store the execution plan in the plan table. The SQL statement can
include bind variables, although the variables will not get bound and the values of the bind
variables will be irrelevant.
If you issue the EXPLAIN PLAN statement from SQL*Plus, you will get back the feedback
message “Explained.” At this point the execution plan for the explained SQL statement has been
inserted into the plan table, and you can now query the plan table to examine the execution plan.
Execution plans are a hierarchical arrangement of simple data access operations. As of the
hierarchy, you need to use a CONNECT BY clause in your query from the plan table. Using the
LPAD function, you can cause the output to be formatted in such a way that the indenting helps
Page 91
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
you traverse the hierarchy. There are many different ways to format the data retrieved from the
plan table. No one query is the best, because the plan table holds a lot of detailed information.
Different DBAs will find different aspects more useful in different situations.
A simple SQL*Plus script to retrieve an execution plan from the plan table is as follows:
REM
REM explain.sql
REM
You have a simple query that you will use in a few examples. You will call this “the
invoice item query.” The query is as follows:
Page 92
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
The explain.sql SQL*Plus script above displays the execution plan for the invoice item query as
follows:
The execution plan shows that Oracle is using nested loops joins to join three tables,
and that accesses from all three tables are by unique index lookup. This is probably a
very efficient query.
When you no longer need an execution plan, you should delete it from the plan table.
You can do this by rolling back the EXPLAIN PLAN statement (if you have not
committed yet) or by deleting rows from the plan table. If you have multiple execution
plans in the plan table, then you should delete selectively by statement_id. Note that if
you explain two SQL statements and assign both the same statement_id, you will get
an ugly cartesian product when you query the plan table!
Page 93
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
The root operation which you explained is a SELECT statement. The output of the
statement will be the results of a sort operation (for the purposes of satisfying the
ORDER BY clause). The input to the sort will be the results of a full table scan of the
customers table. Stated more clearly, the database server will execute this query by
checking every row in the customers table for a criteria match and sorting the results.
Perhaps the developer expected Oracle to use an index on the customer_name
column to avoid a full table scan, but the use of the UPPER function defeated the
index. (A function-based index could be deployed to make this query more efficient.)
Again, the root operation is a SELECT statement. This time, the SELECT statement
gets its input from the results of a nested loops join operation. The nested loops
operation takes as input the results of accesses to the invoices and customers tables.
(You can tell from the indenting that accesses to both tables feed directly into the
nested loops operation.) The invoices table is accessed by a range scan of the
invoices_date index, while the customers table is accessed by a unique scan of
the customers_pk index.
In plainer language, here is how Oracle will execute this query: Oracle will perform a
range scan on the invoices_date index to find the ROWIDs of all rows in the
invoices table that have an invoice date matching the query criteria. For each ROWID
found, Oracle will fetch the corresponding row from the invoices table, look up the
customer_id from the invoices record in the customers_pk index, and use the
ROWID found in the customers_pk index entry to fetch the correct customer record.
This, in effect, joins the rows fetched from the invoices table with their corresponding
matches in the customers table. The results of the nested loops join operation are
returned as the query results.
Page 94
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
It is interesting to note that Oracle chose to use a hash join and a full table scan on the customers
table instead of the more traditional nested loops join. In this database there are many invoices
and a relatively small number of customers, making a full table scan of the customers table less
expensive than repeated index lookups on the customers_pk index. But suppose the customers
table was enormous and the relative number of invoices was quite small. In that scenario a nested
loop join might be better than a hash join. Examining the execution plan allows you to see which
join method Oracle is using. You could then apply optimizer hints to coerce Oracle to use alternate
methods and compare the performance.
Page 95
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
The “other” column in the plan table is a wild card where Oracle can store any sort of textual
information about each step of an execution plan. The other_tag column gives an indication of
what has been placed in the “other” column. This column will contain valuable information during
parallel queries and distributed operations.
Page 96
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
You can enable the SQL Trace facility for a session or for an instance. When the SQL Trace
facility is enabled, performance statistics for all SQL statements executed in a user session or in
the instance are placed into trace files.
The additional overhead of running the SQL Trace facility against an application with performance
problems is normally insignificant compared with the inherent overhead caused by the
application's inefficiency.
Understanding TKPROF
You can run the TKPROF program to format the contents of the trace file and place the output into
a readable output file. Optionally, TKPROF can also:
Determine the execution plans of SQL statements
Create a SQL script that stores the statistics in the database
TKPROF reports each statement executed with the resources it has consumed, the number of
times it was called, and the number of rows which it processed. This information lets you easily
locate those statements that are using the greatest resource
Page 97
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Parameter Description
TIMED_STATISTICS This enables and disables the collection of timed statistics, such as CPU
and elapsed times, by the SQL Trace facility, as well as the collection of
various statistics in the dynamic performance tables. The default value of
false disables timing. A value of true enables timing. Enabling timing
causes extra timing calls for low-level operations. This is a dynamic
parameter. It is also a session parameter.
MAX_DUMP_FILE_SIZE When the SQL Trace facility is enabled at the instance level, every call to
the server produces a text line in a file in the operating system's file
format. The maximum size of these files (in operating system blocks) is
limited by this initialization parameter. The default is 500. If you find that
the trace output is truncated, then increase the value of this parameter
before generating another trace file. This is a dynamic parameter. It is
also a session parameter.
USER_DUMP_DEST This must fully specify the destination for the trace file according to the
conventions of the operating system. The default value is the default
destination for system dumps on the operating system.This value can be
modified with ALTER SYSTEM SET USER_DUMP_DEST= newdir. This
is a dynamic parameter. It is also a session parameter.
Issue the following syntax to set the Timed_statistics initialization parameter to true
ALTER SYSTEM SET TIMED_STATISTICS = TRUE;
After the above step you need to make sure how to distinguish the trace files by name. Oracle
writes trace files to the user dump destination specified by USER_DUMP_DEST. However, this
directory can soon contain many hundreds of files, usually with generated names. It might be
difficult to match trace files back to the session or process that created them. You can tag trace
files by including in your programs a statement like SELECT program_name FROM DUAL.
Page 98
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
The SQL Trace facility is automatically disabled for the session when the application disconnects
from Oracle.
You can enable the SQL Trace facility for an instance by setting the value of the SQL_TRACE
initialization parameter to TRUE in the initialization file.
SQL_TRACE = TRUE
Note: Running the SQL Trace facility increases system overhead, enable it only when tuning SQL
statements, and disable it when you are finished.
After the SQL Trace facility has generated a number of trace files, you can:
Run TKPROF on each individual trace file, producing a number of formatted output
files, one for each session.
Concatenate the trace files, and then run TKPROF on the result to produce a
formatted output file for the entire instance.
TKPROF does not report COMMITs and ROLLBACKs that are recorded in the trace file.
Page 99
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
TKPROF also provides a summary of user level statements and recursive SQL calls for the trace
file.
PARSE Translates the SQL statement into an execution plan, including checks for proper
security authorization and checks for the existence of tables, columns, and other
referenced objects.
EXECUTE Actual execution of the statement by Oracle. For INSERT, UPDATE, and DELETE
statements, this modifies the data. For SELECT statements, this identifies the selected
rows.
FETCH Retrieves rows returned by a query. Fetches are only performed for SELECT
statements.
CPU Total CPU time in seconds for all parse, execute, or fetch calls for the statement.
This value is zero (0) if TIMED_STATISTICS is not turned on.
ELAPSED Total elapsed time in seconds for all parse, execute, or fetch calls for the
statement. This value is zero (0) if TIMED_STATISTICS is not turned on.
Page 100
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
SQL Trace
Meaning
Statistic
DISK Total number of data blocks physically read from the datafiles on disk for all parse,
execute, or fetch calls.
QUERY Total number of buffers retrieved in consistent mode for all parse, execute, or fetch
calls. Usually, buffers are retrieved in consistent mode for queries.
CURRENT Total number of buffers retrieved in current mode. Buffers are retrieved in current
mode for statements such as INSERT, UPDATE, and DELETE.
Statistics about the processed rows appear in the ROWS column
ROWS Total number of rows processed by the SQL statement. This total does not
include rows processed by subqueries of the SQL statement.
For SELECT statements, the number of rows returned appears for the fetch step. For UPDATE,
DELETE, and INSERT statements, the number of rows processed appears for the execute step.
The following listing shows TKPROF output for one SQL statement as it appears in the output file:
SELECT *
FROM emp, dept
WHERE emp.deptno = dept.deptno;
If it is acceptable to have 7.01 CPU seconds and to retrieve 826 rows, then you need not look any
further at this trace output. In fact, a major use of TKPROF reports in a tuning exercise is to
eliminate processes from the detailed tuning phase.
Page 101
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Page 102
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
************************************************************************
********
SELECT a.ename name, b.ename manager
FROM emp a, emp b
WHERE a.mgr = b.empno(+)
Page 103
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Page 104
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Page 105
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Page 106
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Page 107
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
************************************************************************
********
INSERT INTO TKOPTKP
VALUES (1,1)
Page 108
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
************************************************************************
********
INSERT INTO TKOPTKP SELECT * FROM TKOPTKP
call count cpu elapsed disk query current
rows
------- ------ -------- ---------- ---------- ---------- ---------- --
--------
Parse 1 0.00 0.00 0 0 0
0
Execute 1 0.02 0.02 0 2 3
11
Fetch 0 0.00 0.00 0 0 0
0
------- ------ -------- ---------- ---------- ---------- ---------- --
--------
total 2 0.02 0.02 0 2 3
11
Page 109
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Page 110
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Summary
Execution plans are a hierarchical arrangement of simple data access operations.
An execution plan defines how Oracle finds or writes the data, when a query is fired.
Explain plan is statement through which you can see the execution plan chosen by
Oracle.
Execution plan is the sequence of operations that Oracle performs to run the
statement.
Page 111
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
SQL trace and TKPROF are the two basic diagnostic tools that help to monitor and
tune applications.
o SQL Trace facility provides performance information on individual SQL
statements.
o TKPROF program formats the contents of the trace file and places the output in a
readable output file.
Page 112
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Learning Objectives
After completing this session, you will be able to:
Describe Automatic Database Diagnostics Monitor
Explain Automatic SGA Management
An ADDM analysis is performed every time an AWR snapshot is taken and the results are saved in
the database. You can view the results of the analysis using Oracle Enterprise Manager or by
viewing a report in a SQL*Plus session. In most cases, ADDM output should be the first place that
a DBA looks when notified of a performance problem. ADDM provides the following benefits:
Automatic performance diagnostic report every hour by default
Problem diagnosis based on decades of tuning expertise
Time-based quantification of problem impacts and recommendation benefits
Identification of root cause, not symptoms
Recommendations for treating the root causes of problems
Identification of non-problem areas of the system
Minimal overhead to the system during the diagnostic process
It is important to realize that tuning is an iterative process and fixing one problem can cause the
bottleneck to shift to another part of the system. Even with the benefit of ADDM analysis, it can
take multiple tuning cycles to reach acceptable system performance. ADDM benefits apply beyond
production systems; on development and test systems ADDM can provide an early warning of
performance issues.
Page 113
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
The goal of the analysis is to reduce a single throughput metric called DB time. DB time is the
cumulative time spent by the database server in processing user requests. It includes wait time
and CPU time of all non-idle user sessions. DB time is displayed in the V$SESS_TIME_MODEL and
V$SYS_TIME_MODEL views. By reducing DB time, the database server is able to support more
user requests using the same resources, which increases throughput. The problems reported by
the ADDM are sorted by the amount of DB time they are responsible for. System areas that are not
responsible for a significant portion of DB time are reported as non-problem areas.
The types of problems that ADDM considers includes the following:
o CPU bottlenecks - Is the system CPU bound by Oracle or some other
application?
o Undersized Memory Structures: Are the Oracle memory structures, such as the
SGA, PGA, and buffer cache, adequately sized?
o I/O capacity issues: Is the I/O subsystem performing as expected?
o High load SQL statements: Are there any SQL statements which are consuming
excessive system resources?
o High load PL/SQL execution and compilation, as well as high load Java usage
o RAC specific issues: What are the global cache hot blocks and objects; are
there any interconnect latency issues?
o Sub-optimal use of Oracle by the application: Are there problems with poor
connection management, excessive parsing, or application level lock contention?
o Database configuration issues: Is there evidence of incorrect sizing of log files,
archiving issues, excessive checkpoints, or sub-optimal parameter settings?
o Concurrency issues: Are there buffer busy problems?
o Hot objects and top SQL for various problem areas
ADDM also documents the non-problem areas of the system. For example, wait event classes that
are not significantly impacting the performance of the system are identified and removed from the
tuning consideration at an early stage, saving time and effort that would be spent on items that do
not impact overall system performance. In addition to problem diagnostics, ADDM recommends
possible solutions. When appropriate, ADDM recommends multiple solutions for the DBA to
choose from. ADDM considers a variety of changes to a system while generating its
recommendations. Recommendations include the following:
Hardware changes: Adding CPUs or changing the I/O subsystem configuration
Database configuration: Changing initialization parameter settings
Schema changes: Hash partitioning a table or index, or using automatic segment-
space management (ASSM)
Application changes: Using the cache option for sequences or using bind variables
Using other advisors: Running the SQL Tuning Advisor on high load SQL or running
the Segment Advisor on hot objects
Page 114
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
Each problem finding is quantified by an impact that is an estimate of the portion of DB time
caused by the finding's performance issue. A problem finding can be associated with a list of
RECOMMENDATIONs for reducing the impact of the performance problem. Each recommendation
has a benefit which is an estimate of the portion of DB time that can be saved if the
recommendation is implemented. A list of recommendations can contain various alternatives for
solving the same problem; you not have to apply all the recommendations to solve a specific
problem.
Recommendations are composed of ACTIONs and RATIONALEs. You need to apply all the
actions of a recommendation in order to gain the estimated benefit. The rationales are used for
explaining why the set of actions were recommended and to provide additional information to
implement the suggested recommendation.
SQL statements were not shared due to the usage of literals. This resulted in additional hard
parses which were consuming significant database time.
ACTION: Investigate application logic for possible use of bind variables instead of literals.
Alternatively, you may set the parameter "cursor_sharing" to "force".
In this example, the finding points to a particular root cause, the usage of literals in SQL
statements, which is estimated to have an impact of about 31% of total DB time in the analysis
period. The finding has a recommendation associated with it, composed of one action and one
rationale. The action specifies a solution to the problem found and is estimated to have a
maximum benefit of up to 31% DB time in the analysis period. Note that the benefit is given as a
portion of the total DB time and not as a portion of the finding's impact. The rationale provides
additional information on tracking potential SQL statements that were using literals and causing
this performance issue. Using the specified plan hash value of SQL statements that could be a
problem, a DBA could quickly examine a few sample statements.
Page 115
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
A system global area (SGA) is a group of shared memory structures that contain data and control
information for one Oracle database instance. If multiple users are concurrently connected to the
same instance, then the data in the instance's SGA is shared among the users. Consequently, the
SGA is sometimes called the shared global area.
Shared Database
Pool buffer cache Log Buffer
(auto tuned) (auto tuned)
Part of the SGA contains general information about the state of the database and the instance,
which the background processes need to access; this is called the fixed SGA. No user data is
stored here. The SGA also includes information communicated between processes, such as
locking information.
The task of manually adjusting the sizes of individual SGA components could pose a few
challenges. It may not be easy to determine the optimal sizes of these components suitable for a
given workload. Oracle9i Database alleviated this problem to a great extent by introducing
advisory mechanisms that allow DBAs to determine the optimal sizes of the buffer cache and
shared pool. However, these recommendations still had to be implemented by the administrator.
This challenge is further compounded in situations in which the workload tends to vary with the
time of the day e.g., online users during the day and batch jobs at night. Sizing for peak load could
mean memory wastage while under-sizing may cause out-of-memory errors (ORA-4031).
Page 116
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
For example if a system is configured with a big large pool to accommodate a nightly RMAN
backup job, most of this memory – which could have been better utilized in the buffer cache or
shared pool for OLTP activity remains unused for the most part of the day. At the same time, the
cost of failures could be prohibitive from a business point of view leaving administrators with few
other options.
The SGA_TARGET parameter reflects the total size of the SGA and includes memory for:
Fixed SGA and other internal allocations needed by the Oracle instance
Log buffer
Shared Pool
Java Pool
Buffer Cache
Keep/Recycle buffer caches (if specified)
Non standard block size buffer caches (if specified)
Streams Pool (new in Oracle Database 10g)
An important point to note is that SGA_TARGET includes the entire memory for the SGA. Thus,
SGA_TARGET allows the user to precisely control the size of the shared memory area allocated by
Oracle.
The performance of each of these components is also monitored by the Oracle instance. The
instance uses internal views and statistics to determine how to optimally distribute memory among
the automatically sized components. As the workload changes, memory is redistributed to ensure
optimal performance with the new workload. This algorithm is never complacent and always tries
to find the optimal distribution by taking into consideration long term as well as short terms trends.
The administrator can still exercise some control over the sizes of the auto-tuned components by
specifying minimum values for each of these components. This can be useful in cases in which the
administrator knows that an application needs a minimum amount of memory in certain
components to function properly. The minimum value of a component is specified by setting the
corresponding parameter for the component.
Page 117
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
In the earlier example, the shared pool and the default buffer pool will not be sized below the
specified values (32M and 20M, respectively). This implies that the remaining 80M can be
distributed across all the components. The actual distribution of values between the SGA
components may be as follows:
Actual Shared Pool Size = 92M
Actual buffer cache size = 20M
Actual java pool size = 16M
Actual Large Pool Size = 0M
Other = 4M
The fixed view V$SGA_DYNAMIC_COMPONENTS displays the current size of each SGA component
while the parameter values (For example,DB_CACHE_SIZE, SHARED_POOL_SIZE) specify the
minimum values. The current sizes of the SGA components can also be obtained by looking at the
Enterprise Manager Memory configuration page.
Page 118
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
The instance has only 224M (256 – 32) remaining to be distributed among the automatically sized
components
Let us illustrate this with an example. Consider a manual configuration in where 1G of memory is
available for SGA and distributed as follows (for the purpose of simplicity you ignore other SGA
components for now):
SHARED_POOL_SIZE=128M
DB_CACHE_SIZE=896M
In this case, if the application ever tries to allocate more than 128M of memory from the shared
pool, it will receive an ORA-4031 indicating that available shared pool has been exhausted. Note
that when this condition happens, there may be free memory in the buffer cache - but it is not
accessible to the shared pool. The user will then manually have to shrink the buffer cache and
grow the shared pool to work around this problem.
Enhanced Performance
Besides maximizing the use of available memory, the Automatic Shared Memory Management
feature can enhance workload performance as well. With manual configuration, it is possible that
compiled SQL statements will frequently age out of the shared pool because of its inadequate size.
This will manifest in terms of frequent hard parses and, hence, reduced performance.
Page 119
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
However when automatic management is enabled, the internal tuning algorithm will monitor the
performance of the workload and grow the shared pool if it determines that doing so will reduce the
number of parses required. This is one of the most wonderful aspects of Automatic Shared
Memory Management feature since it provides enhanced out-of-box performance, without
requiring any additional resources or manual tuning effort.
Ease of Use
Having just a single parameter to deal with greatly simplifies the job of administrators. DBAs can
now just specify the amount of SGA memory an instance has its disposal and forget about the rest.
They do not need to figure out the sizes of individual components any more. In addition, they can
be assured of the fact that no out of memory errors will be generated unless the system has truly
run out of memory.
The preceding parameters can be replaced with SGA_TARGET = 256 M + 512M + 256 M + 16M +
16 M (fixed SGA overhead) = 1056 M
Automatic Shared Memory Management may also be enabled dynamically. If you are using
Enterprise Manager, then you can enable SGA tuning by clicking the enable button on the SGA
screen in the memory parameters section.
Page 120
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
When enabling the Automatic Shared Memory Management feature using EM, the appropriate
value for SGA_TARGET is automatically calculated according to the formula described above. In
addition, EM also unsets all the parameters specifying the size of individual components in order to
maximize the benefit of automatic management.
If using command line interface, then the steps involved in enabling Automatic Shared Memory
Management are as follows:
Dynamically set SGA_TARGET to the current SGA size. The current size of the SGA
can be determined from the fixed-view V$SGA by the following query:
Select sum(value) from v$sga;
Next dynamically set each of the auto-tuned component sizes to zero so that the
automatic shared memory tuning algorithm can modify the sizes as needed.
Page 121
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
If the earlier query for example returns the result of 536870912 (or 512M) then the steps for
enabling auto SGA are as follows:
Alter system set sga_target=512M;
Alter system set shared_pool_size = 0;
Alter system set large_pool_size = 0;
Alter system set java_pool_size = 0;
The change in the amount of physical memory consumed when SGA_TARGET is modified depends
on the OS platform. On some UNIX platforms that do not support dynamic shared memory, the
physical memory in use by the SGA is equal to the value of SGA_MAX_SIZE. On such platforms,
there is no real benefit in running with a value of SGA_TARGET less than SGA_MAX_SIZE and
setting SGA_MAX_SIZE on those platforms is, therefore, not recommended. On other platforms,
such as Solaris and Windows, the physical memory consumed by the SGA is equal to the value of
SGA_TARGET parameter.
Note that when SGA_TARGET is resized, the only components to be affected are the auto-tuned
components. Any manually configured components remain unaffected.
For example, if you have an environment with the following configuration:
SGA_MAX_SIZE=1024M
SGA_TARGET = 512M
DB_8K_CACHE_SIZE = 128M
In this example, the value of SGA_TARGET can be resized up to 1024M and can also be lowered
until one or more of the buffer cache, shared pool, large pool, or java pool reaches its minimum
size (the exact value depends on environmental factors such as the number of CPUs on the
system). But the value of DB_8K_CACHE_SIZE will remain fixed at all times at 128M.
Also, when SGA_TARGET is reduced, if the values for any auto-tuned component sizes have been
specified to limit their minimum sizes, then those components will not shrink below their respective
minimums. Therefore, if you have the following combination of parameters:
SGA_MAX_SIZE=1024M
SGA_TARGET = 512M
DB_CACHE_SIZE = 96M
DB_8K_CACHE_SIZE = 128M
In this example, in addition to the DB_8K_CACHE_SIZE being permanently fixed at 128M, the
primary buffer cache will not shrink below 96M. This imposes an additional restriction on how far
the value of SGA_TARGET can be reduced.
Page 122
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
CONCLUSION
Memory is a precious system resource and administrators currently spend a significant amount of
their time optimizing its use. With Automatic Shared Memory Management, they are relieved of
this time consuming and often tedious exercise. The flexibility of this solution will ensure the best
possible utilization of existing resources and thereby help organizations reduce capital
expenditure. Just another example of how the Oracle Database 10g is going to let administrators
play more strategic roles and allow businesses to become more profitable!
Summary
ADDM collects data from AWR in a periodic time and gives suggestion for problem
areas.
Goal of ADDM report analysis is to reduce the single throughput metric – DBTIME.
Types of problems that ADDM considers are as follows:
o CPU bottlenecks
o Undersized Memory Structures
o I/O capacity issues
o High load SQL statements
SGA contains data and control information for one oracle database instance.
One of key self-management enhancements in Oracle 10g is automatic SGA
management.
Page 123
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
References
Websites
Oracle® Database Performance Tuning Guide10g – Oracle database Documentation
library.
Oracle® Database Performance Tuning Guide Oracle 10g release 2 Documentation
library
http://dba-oracle.com/art_sql_tune.htm
http://www.databasejournal.com/features/oracle/article.php/10893_3341851_2
Books
Oracle SQL Tuning Pocket Reference by Mark Gurry
Oracle® SQL by Example, Third Edition by Alice Rischert
Sams Teach Yourself SQL® in 24 Hours, Third Edition
SQL Performance Tuning by Peter Gulutzan; Trudy Pelzer
Oracle SQL Tuning Pocket Reference by Mark Gurry
Page 124
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected
Handout – Oracle 10g PL/SQL Performance Tuning
STUDENT NOTES:
Page 125
©Copyright 2007, Cognizant Technology Solutions, All Rights Reserved
C3: Protected