PURPOSE
Query Tuning issues can often be alleviated by modification of the query in question, either to add hints or to change the query structure to avoid an issue. However in some cases the query cannot be modified because it is hardcoded in an application or is generated by application code. This document suggests methods that you can use to attempt to alter the access path taken by a SQL query without changing it.
SCOPE & APPLICATION
N.B. Much of the information discussed here is recorded in other articles. However, the idea of this article is to group the required information together and reference other material as necessary. Also note that some of the suggestions will have no affect on queries that use the Rule based optimizer because they are specific to Cost based. These suggestions are highlighted as such.
SQL Query Tuning suggestions
There are usually 2 situations when a query needs be tuned.
- Query cannot be modified (e.g. where the query is generated from within the application).
- Query in question can be modified
Query cannot be modified
Often a query that is performing badly cannot be modified. This may be because the query is embedded in an application or is generated code. There are a number of possibilities for tuning such queries.
Remember that all these options can also be used for queries that can be edited.
N.B. It should be noted that all the suggestions below are workarounds to the problem of inflexibility in the front end application. Oracle provides a mechanism to modify the query plan (hints). Ultimately, if none of the workarounds below are acceptable there is little that can be done. In this case, perhaps the base application needs to be modified to accept query hints...
- Modify Statistics (CBO ONLY)
Gather table statistics with a different sample size:
Choosing a different sample size may gather statistics that reflect the actuality of your data more closely. Usually a higher sample size is recommended but sometimes a lower sample or even no statistics can give the desired results. See the following articles for information regarding gathering statistics: Note:114671.1 and Note:44961.1
Add histograms to relevant columns:
Column histograms are a valuable tool that can increase the accuracy of statistics for columns with an uneven data distribution. Changing column statistics modifies the selectivity for predicates on those columns and so can have a favourable affect on queries. See Oracle9i Database Performance Guide and Reference Page 3-20 “Using Histograms” for more details.
- Add or remove indexes (BOTH CBO/RBO)
Additional indexes may provide a better access path for slow queries. Equally an unselective index may be causing an inefficient access path. The CBO should be able to determine the relative usefulness of different indexes if the statistics provided are adequate. If indexes are causing a problem but cannot be removed then they can be disabled using hints or other methods. See Note:122986.1
- Are there 8 or more tables in the join?
If so then the CBO may not be even considering the join order that you want to use. Consider using the Parameter:OPTIMIZER_MAX_PERMUTATIONS parameter to change the maximum number of permutations considered. Also See Note:73489.1 for information on maximum permutations considered by the optimizer.
- Create a view with embedded hints (BOTH CBO/RBO)
Often creating and then referencing a view that contains hints that force the access path that you require can force a desired access path. This is especially useful for distributed queries where a view can be built on a remote node. There is a distributed query example in Note:33838.1 Determining the execution plan for a distributed query
- Create a Materialised View (Snapshot) (BOTH CBO/RBO)
This is similar to view creation except that you store the query results somewhere. It operates by prefetching some or all of the data for the query so that it does not have to be fetched at execution time. See the Oracle9i Data Warehousing Guide Chapter 8 “Materialized Views”
- Modify Instance Parameters (BOTH CBO/RBO)
Modification of Instance wide parameters can help change the access path for queries but be aware that it may also change other access paths in a detrimental fashion.
- Modify the degree of parallelism on the table/indexes (CBO ONLY)
Modifying the degree of parallelism on a table can cause the plan to change. Increasing the degree of parallelism is likely to make full table scans appear cheaper and more attractive while reducing it will make FTS look less attractive and ultimately will stop PQO being used (if degree set to 1 or noparallel). See Note:203238.1 Using Parallel Query for more details.
- Consider using stored outlines to maintain the desired access path (CBO ONLY)
Test system where the good plan can be generated
This plan that could be stored and then transferred to the live environment.
Generation of a good plan for storing as an outline by Manipulating the schema to force a specific plan
For example by removing all the indexes that should not be selected / making indexes look very attractive for example by using punitive FTS parameters (reduce DB_FILE_MULTIBLOCK_READ_COUNT to 1) and encouraging index parameters (OPTIMIZER_INDEX_COST_ADJ & OPTIMIZER_INDEX_CACHING) a desired plan may be chosen since no other choices are available. Then storing an outline under these conditions, reverting the changes and applying the outline to force the desired plan.
For reference, please refer to:
@ Also See Note:92202.1 which shows how you can manipulate outlines – this is NOT supported.
Query can be modified
- Add Hints (BOTH CBO/RBO)
Hints are directives added to the select list of a query. They force the query to operate in a particular manner. Hints are available to alter all manner of factors that affect queries including single table access methods, join order and methods.
See Note:29236.1 QREF: SQL Statement HINTS
Advanced hint usage:
See the following notes for more information on using hints effectively:
- Create inline views (BOTH CBO/RBO)
Inline views are a technique that effectively embeds a view definition within the from clause of a query. It is useful as the inline view can be modified to prevent merging occurring and force query blocks to be executed separately from the rest of the query due to view merging restrictions. Forcing the query block to execute separately can also have performance benefits in some circumstances.
- Add more selective predicates (BOTH CBO/RBO)
It is possible that the existing predicates for a query are unselective and that other predicates can be added to reduce the result set earlier in the query execution. This may have the effect of reducing the number of rows handled by the query early on and affect the performance of the query. Obviously it is important not to change the result of the query.
- Divide up the work of one query into multiple queries (BOTH CBO/RBO)
A query may be able to be broken into a number of smaller queries. These could then be run concurrently or serially. The effect of this may be to reduce memory and sort space requirements. The outputs of the smaller queries could be inserted in to a temporate the global result.
- Rewrite the query in plsql (BOTH CBO/RBO)
It may be possible to rewrite the query in pl/sql and thus take advantage of the procedural code that this offers. Some queries can benefit from running procedurally.
- Rewrite the query (BOTH CBO/RBO)
Re-writing a complex query may open up additional access paths or force the query to operate in a different way.
Final Note
Remember that if your query:
- Returns large volumes of data
- Has unselective predicates that cause much data to be searched to return the data you want
- Is maxing out physical aspects of the hardware
RELATED DOCUMENTS
Note:73489.1 Affect of Number of Tables on Join Order Permutations
Note:33838.1 Determining the execution plan for a distributed query
Note:203238.1 Using Parallel Query
@ Note:92202.1 Manipulating Stored Outlines – this is NOT supported
Note:29236.1 QREF: SQL Statement HINTS
Note:50607.1 How to specify an index hint
Note:62364.1 Hints and subqueries
Note:69992.1 Why is my hint ignored?
Note:68084.1 Using hints to optimize an Update with subquery not using index on updated table
No comments:
Post a Comment