Oracle Enterprise Manager Database Tuning with the Oracle Tuning Pack
Release 9.0.1

Part Number A86647-01

Library

Product

Contents

Index

Go to previous page Go to next page

6
Tuning SQL Statements

This chapter contains the following topics:

Tuning SQL Statements

Oracle SQL Analyze is a flexible tool that allows you to approach tuning from different perspectives.

For example, you may have selected a statement through TopSQL, analyzed its performance and determined the appropriate measures to tune the statement. Whether that method is to edit the syntax manually or add hints through the Hint Wizard, you've determined exactly what you need to do.

Or you might have a statement stored in a file that you know needs tuning. Rather than examine the performance statistics, you would rather process the statement through the SQL Tuning Wizard and have the Wizard tune your statement automatically.

This chapter first describes manual editing and methodologies, and then explains how to use the Hint and SQL Tuning Wizards to automate the tuning process.

Editing Statements Manually

You can edit statements manually by entering text into the SQL Text window. Although Oracle SQL Analyze will not check your syntax while you are typing, you can still test the statement by generating explain plans, executing the statement, and comparing its results to previous versions of the statement, or to other statements you have analyzed.

You will not be able to edit a statement if either of the following is true:

If either of these cases is true, select SQL=>Create Like to create an editable copy of the statement. A SQL statement object is created in the navigation window for the new statement. Then proceed to edit the new statement.

Understanding Index Tuning Recommendations

Effective indexing can improve the performance of your SQL statements by reducing the need for full table scans. Oracle SQL Analyze can generate recommendations that will help you improve index effectiveness, and generate scripts you can use to carry out the recommendations.

Note: The Index recommendations feature is designed to tune indexes that will be used by the Oracle cost-based optimizer. You are encouraged, however, to compare the results of using either a cost-based or rule-base optimizer.

The index tuning evaluation can take several minutes depending on the number of tables being evaluated and the number of SQL statements in the SQL History. You can use Oracle SQL Analyze for other SQL tuning operations while this operation is being performed.

If Oracle SQL Analyze determines that index changes are necessary, it will provide a tree list of index recommendations. The recommendations are organized by table.

You can view the details for a recommendation by either double-clicking on the recommendation or highlighting it and using the right mouse button to access Recommendation Details. The Recommendation Details provide some important information, such as:

Getting Index Recommendations

You can perform index tuning for a selected SQL statement by selecting SQL=>Get Index Recommendations.

The Get Index Recommendations feature will identify the tables accessed in the SQL statement and will scan the database SQL History for any other SQL statements that reference those tables. This subset of the SQL History is then used to evaluate the index requirements for the target tables. In this way, index tuning for a selected SQL statement is performed in the context of the larger SQL workload.

The index tuning evaluation can take several minutes depending on the number of tables being evaluated and the number of SQL statements in the SQL History. You can use SQL Analyze for other SQL tuning operations while this operation is being performed. If SQL Analyze determines that index changes are necessary it will provide a tree list of index recommendations. The recommendations are organized by table.

Once you have index recommendations you can:

Generating Tuning Implementation Scripts

You can create a SQL script to implement Tuning Index recommendations:

  1. Highlight the SQL object in the navigator tree that contains the Index Recommendations, and select SQL=>Generate Implementation Script.

  2. A Save As dialog box appears.

  3. Enter the file name and path for the implementation script.

  4. The file is saved in the specified location. You can edit and execute this script using the Oracle Enterprise Manager SQL Worksheet.

Alternatively, you can schedule the Implementation Script for execution using the Oracle Enterprise Manager Console Job System. Refer to the Oracle Enterprise Manager Administrator's Guide for information on this feature.


Note:

The Virtual Index Wizard allows you to test and understand how a new index will affect SQL performance. You can define an index and then without actually creating the index, understand how this index would affect the execution plan for an individual SQL statement. For more information on using the Virtual Index Wizard with SQL Analyze, see the online help provided with the wizard. 


Understanding Hints

As an application designer, you may know information about your data that the optimizer cannot. For example, you may know that a certain index is more selective for certain queries than the optimizer can determine. Based on this information, you may be able to choose a more efficient execution plan than the optimizer. In such a case, you can use hints to force the optimizer to use your chosen execution plan.

You can use hints to specify:

Specifying Hints

Hints apply only to optimization of the statement block in which they appear. A statement block is any one of the following statements or parts of statements:

You can send hints for a SQL statement to the optimizer by enclosing them in a Comment within the statement.

A statement can have only one Comment containing hints. This Comment can only follow the SELECT, UPDATE, or DELETE keyword.

If you specify hints incorrectly, Oracle ignores them but does not return an error:

Oracle also ignores hints in all SQL statements in environments which use PL/SQL Version 1.

The optimizer only recognizes hints when using the cost-based approach. If you include any hint (except the RULE hint) in a statement block, the optimizer automatically uses the cost-based approach.

For more information about comments and hints, see the Oracle SQL Analyze online help, and the Oracle9i Performance Guide and Reference.

The following hints, organized according to the optimization area they impact, can be added to your SQL statement manually or using the Hint Wizard.

Note that the availability of some hints is limited by the database version.


Note:

For more information on any of these hints, see the Oracle9i Database Performance Guide and Reference.


Optimization Approaches

Access Methods

ALL_ROWS

AND_EQUAL

CHOOSE

CLUSTER

FIRST RULES

FULL

RULE

HASH

Parallel Execution

HASH_AJ

APPEND*ORDERED

HASH_SJ ***

STAR**

INDEX

STAR_TRANSFORMATION*

INDEX_ASC

Join Operations

INDEX_COMBINE*

DRIVING_SITE*

INDEX_DESC

USE_HASH**

INDEX_FFS*

USE_MERGE

MERGE_AJ**

USE_NL

MERGE_SJ***

Additional Hints

ROW_ID

CACHE

USE_CONCAT

NOCACHE

NO_EXPAND***

PUSH_SUBQ

REWRITE***

MERGE***

NOREWRITE***

NO_MERGE*

Join Orders

PUSH_JOIN_PRED***

NO_PUSH_JOIN_PRED***

NOAPPEND*

ORDERED PREDICATES***

NOPARALLEL

PARALLEL

PARALLEL_INDEX*

NO_PARALLEL_INDEX***

* Available only for Oracle8 databases

**Available only for Oracle7.3 and Oracle8 databases

***Available only for Oracle8i databases 

Understanding Rules-of-Thumb

The syntax of SQL statements has a significant affect on performance. The use of certain command clauses can disable indexes or cause inefficient data sorting and filtering. In some cases, the order in which command clauses are used or the order in which data and tables are referenced can add an extra burden on resources.

Oracle SQL Analyze contains a set of rules, developed by database experts, that evaluates SQL statements and suggests alternative statements, when possible. These rules focus on principles of optimizing performance, such as:

Oracle SQL Analyze applies these "rules-of-thumb" when you tune a statement with the Tuning Wizard, and supplies alternative SQL statements when possible. Oracle SQL Analyze checks your statement against the following rules, which are explained in this section:

Use NOT EXISTS instead of NOT IN

Using NOT EXISTS instead of NOT IN adds a limiting condition to your queries that can reduce the number of full table scans necessary.

The following example uses a NOT IN clause to find names and department IDs in the DEPARTMENT table where the department ID does not also exist in the EMPLOYEE table:

	SELECT name, department_id
FROM department
WHERE department_id NOT IN
(SELECT department_id FROM employee)

Because NOT IN does not use a limiting condition, Oracle will perform a full table scan of DEPARTMENT. For each record in DEPARTMENT, the subquery will be executed. Since the subquery has no limiting WHERE clause, it will perform a full table scan for every record in the full table scan of DEPARTMENT.

Instead, NOT EXISTS can be used so that nested index scans will be used in the subquery for each row in the DEPARTMENT table. The logic of the NOT EXISTS clause tells Oracle not to return the row if it finds a match in both tables. The only records that will be returned from DEPARTMENT are those that return no rows from the subquery, and no full table scans are performed by the subquery. The following statement, therefore, is more efficient than the previous example.

SELECT name, department_id
FROM department,
WHERE NOT EXISTS
(SELECT department_id
FROM employee
WHERE department.department_id=employee.department_id)

Use NOT EXISTS or NOT IN with hints instead of MINUS

MINUS returns the set of rows from one query that is not present in the set of rows returned by a second query. Rewriting queries using NOT EXISTS or NOT IN can enable them to take advantage of indexes, reducing the number of full table scans a clause may require.

In some cases, Oracle SQL Analyze might determine that because a hash anti-join (HASH_AJ) usually does not require a sort, it will produce better results than MINUS.

The following query, for example, matches names and birthdates in the EMPLOYEE table with those in the STOCKHOLDER table, then returns the names and birthdates of employees who are not stockholders. Because MINUS does not use indexes, Oracle will use two full table scans and perform a sort on each table before the MINUS operation can be performed.

SELECT birth_date, last_name, first_name
FROM employee 
MINUS
SELECT birth_date, last_name, first_name
FROM stock_holder

If the statement is re-written using NOT EXISTS, Oracle can use nested index scans in the subquery for rows in the primary statement.

SELECT birth_date, last_name, first_name
FROM employee 
WHERE NOT EXISTS
(SELECT 1
	FROM stock_holder
WHERE stock_holder.birth_date = employee.birth_date
	AND stock_holder.first_name = employee.first_name)

If Oracle SQL Analyze determines that a hash anti-join will produce better results, the example query could be rewritten to use two full table scans and an anti-join algorithm to join the rows, instead of performing sort and minus operations.

SELECT birth_date, last_name, first_name
FROM employee 
WHERE (birth_date, last_name, first_name)NOT IN
(SELECT /*+ hash_aj (stock_holder) */ birth_date, last_name, first_name
FROM stock_holder)

Use TRUNC differently to enable indexes

Using the truncate command (TRUNC) on an indexed column disables the index. Rewriting your query so that fewer columns are truncated allows it to take advantage of indexes to increase performance.

In the following example, trans_date is an indexed column, but the index is disabled by the TRUNC command.


SELECT account_name, trans_date
FROM transaction
WHERE TRUNC(trans_date) = TRUNC(sysdate)

The query can be rewritten as shown below to use the trans_date index and increase performance.

SELECT account_name, trans_date
FROM transaction
WHERE trans_date BETWEEN TRUNC(sysdate) AND TRUNC(sysdate) + .99999

Use operators differently to enable indexes

The optimizer does not use an index if the indexed column is part of a function (in the WHERE clause). If Oracle SQL Analyze determines that an equation can be rewritten to avoid the use of operators, it can rewrite the statement as shown below.

In this example, the equation in the query can be rewritten as a simple inequality clause. statement. Therefore the query

SELECT account_name, trans_date, amount
FROM transaction
WHERE amount + 3000 < 5000

can be rewritten as


SELECT account_name, trans_date, amount
FROM transaction
WHERE amount < 2000

Do not use columns on both sides of operator

When an indexed column appears on both sides of an operator, the index for that column is disabled. Oracle SQL Analyze detects this condition and, when possible, rewrites the statement to allow the index to be used.

In the following example, the column account_name is indexed, but the index is disabled.

SELECT account_name, trans_date, amount
FROM transaction
WHERE account_name = NVL(:acc_name, account_name)

The query can be rewritten using LIKE so that the indexed column is only on one side of the operator.

SELECT account_name, trans_date, amount
FROM transaction
WHERE account_name LIKE NVL(:acc_name, `%')

Use WHERE in place of HAVING

The HAVING clause limits rows collected by a GROUP BY clause only after they have been aggregated. Whenever possible, it is better to limit the number of rows retrieved before they are merged and sorted into an aggregation. Using WHERE in place of HAVING eliminates rows before they are added to the aggregation.

The statement below sorts an entire list of items by quantity, then removes from the aggregation all items with a quantity less than 40.

SELECT quantity, AVG(actual_price)
FROM item
GROUP BY quantity
HAVING quantity > 40

The statement can be rewritten so that all rows where QUANTITY is less than 40 are removed before the aggregation is sorted.

SELECT quantity, AVG(actual_price)
FROM item
WHERE quantity >40
GROUP BY quantity

Note that if the HAVING clause is applied to aggregate functions, it cannot be replaced by WHERE. In the query below, for example, HAVING is applied to a SUM function.

SELECT program_name
   	,count
   	,min(end_date-start_date) "Min Runtime"
   	,avg(end_date-start_date)"Avg Runtime"
   	,max((end_date-start_date)"Max Runtime"
   	,sum(end_date-start_date)"tot Runtime"
FROM jobs
WHERE start_date>sys_date - 7
GROUP BY program_name
HAVING sum((end_date-start_date)>0.25 or max(end_date-start_date) > 0.04

Use UNION ALL instead of UNION

The difference between the UNION and UNION ALL is that UNION requires a sort operation to eliminate any rows that are duplicated across the two row sets, while UNION ALL returns all rows, even if they are duplicated. If duplicated rows are not important, using UNION ALL can avoid potentially expensive sorts, merges, and filtering operations.

For example, the statement

SELECT acct_num, balance_amt
FROM debit_transactions
WHERE tran_date = `31-DEC-99'
UNION
SELECT acct_num, balance_amt
FROM credit_transactions
WHERE tran_date = `31-DEC-99'

Can be rewritten as

SELECT acct_num, balance_amt
FROM debit_transactions
WHERE tran_date = `31-DEC-99'
UNION ALL
SELECT acct_num, balance_amt
FROM credit_transactions	
WHERE tran_date = `31-DEC-99'

Using the SQL Tuning Wizard

The SQL Tuning Wizard guides you through the entire SQL statement tuning process. It evaluates your SQL Statement using Rules-of-Thumb to generate alternate, optimized versions of your SQL statement.

To use the SQL Tuning Wizard:

Select Tools=>SQL Tuning Wizard. This launches the SQL Tuning Wizard.

The SQL Tuning Wizard Process

The SQL Tuning Wizard is an automated guide that leads you through tuning a SQL statement. Throughout the process, you will be able to make choices that will help the wizard optimize your specific SQL statement. If you need more information to make your choices, select the Help button from any of the wizard pages.

The SQL Tuning Wizard will guide you through the following processes:

Using the Hint Wizard

The Hint Wizard identifies hints in a statement and allows the user to present other hints that can be added to the statement. It provides a description for a selected hint and will automatically generate a new SQL statement if a hint is added or deleted.

To use the Hint Wizard:

Select Tools=>Hint Wizard. The Hint Wizard will guide you through the rest of this process.

  1. Select a subquery to analyze from the Hint Wizard page.

  2. View/delete the current hints.

  3. Select a new hint to add, and supply:

    • table parameters, if necessary.

    • index parameters, if necessary.

  4. Review the current hints.

  5. Apply hints to the SQL statement.

Figure 6-1 Hint Wizard Opening Screen


Text description of hint.gif follows.
Text description of the illustration hint.gif

Go to previous page Go to next page
Oracle
Copyright © 2001 Oracle Corporation.

All Rights Reserved.

Library

Product

Contents

Index