从事IT基础架构多年,发现自己原来更合适去当老师……喜欢关注新鲜事物,不仅限于IT领域。
分类: Oracle
2007-02-05 15:10:53
Proper Development Environment
Many infrastructure issues must be addressed in order to avoid surprises with SQL optimization. Shops that do not create this infrastructure are plagued by constantly changing SQL execution plans and poor database performance.
The key to success with the CBO is stability and ensuring your success with the CBO involves several important infrastructure issues.
Let's take a closer look at these issues.
Re-analyze statistics only when necessary. It is very rare for the fundamental nature of a schema to change; large tables remain large, and index columns rarely change distribution, cardinality, and skew. You should only consider periodically re-analyzing your total schema statistics if your database matches these criteria:
Because SQL is a declarative language, a query can be written in many different ways, each with a different execution plan. For example, all of the following SQL queries give the correct answer, but with widely varying execution plans:
-- Form one using non-correlated subquery) select book_title from book where book_key not in (select book_key from sales); Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=1 Bytes=64) 1 0 FILTER 2 1 TABLE ACCESS (FULL) OF 'BOOK' (Cost=1 Card=1 Bytes=64) 3 1 TABLE ACCESS (FULL) OF 'SALES' (Cost=1 Card=5 Bytes=25) -- Form two using outer join select book_title from book b, sales s where b.book_key = s.book_key(+) and quantity is null; Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=3 Card=100 Bytes=8200) 1 0 FILTER 2 1 FILTER 3 2 HASH JOIN (OUTER) 4 3 TABLE ACCESS (FULL) OF 'BOOK' (Cost=1 Card=20 Bytes=1280) 5 3 TABLE ACCESS (FULL) OF 'SALES' (Cost=1 Card=100 Bytes=1800) -- Form three using correlated subquery select book_title from book where book_title not in ( select distinct book_title from book, sales where book.book_key = sales.book_key and quantity > 0); Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=1 Card=1 Bytes=59) 1 0 FILTER 2 1 TABLE ACCESS (FULL) OF 'BOOK' (Cost=1 Card=1 Bytes=59) 3 1 FILTER 4 3 NESTED LOOPS (Cost=6 Card=1 Bytes=82) 5 4 TABLE ACCESS (FULL) OF 'SALES' (Cost=1 Card=5 Bytes=90) 6 4 TABLE ACCESS (BY INDEX ROWID) OF 'BOOK' (Cost=1 Card=1) 7 6 INDEX (UNIQUE SCAN) OF 'PK_BOOK' (UNIQUE)
As we can see, the proper formulation of the query has a dramatic impact on the execution plan for the SQL. Savvy Oracle developers know the most efficient way to code Oracle SQL for optimal execution plans, and savvy Oracle shops train their developers to formulate efficient SQL.
Some techniques for assisting developers in tuning their SQL include:
It is an important job of the Oracle DBA to properly gather and distribute statistics for the CBO. The goal of the DBA is to keep the most accurate production statistics for the current processing. In some cases, there may be more than one set of optimal statistics. For example, the best statistics for OLTP processing may not be the best statistics for the data warehouse processing that occurs each evening. In this case, the DBA will keep two sets of statistics and import them into the schema when processing modes change.
Exporting CBO statistics is done with the export_system_stats procedure in the dbms_stats package. In this example we export the current CBO statistics into a table called stats_table_oltp:
dbms_stats.export_system_Stats('stats_table_oltp');
When captured, we can move the table to other instances and use the import_system_stats procedure in dbms_stats to overlay the CBO statistics when processing modes change:
dbms_stats.import_system_stats('stats_table_oltp'); dbms_stats.import_system_stats('stats_table_dss');
Change CBO parameters only rarely. Many Oracle shops change the fundamental characteristics of their CBO by changing the global CBO parameters. Especially dangerous are changes to optimizer_mode, optimizer_index_cost_adj, and optimizer_index_caching, and these changes should only be made when a sound reason exists. Other CBO parameters such as hash_area_size and sort_area_size are less dangerous and can be set at the individual session level to change the CBO evaluates a query.
Ensure static execution plans. Remember, re-analyzing a schema could cause thousands of SQL statements to change execution plans. Many Oracle shops have implemented standards that require that all SQL, when tested and approved in their test environment, function identically in production.
The only way to achieve this mandate is to migrate the statistics that were used in SQL testing into the production environment when the SQL is migrated. However, the DBA must ensure that amigration of statistics from test into production does not adversely affect the execution plans of other SQL that touch the target table. Hence, the DBA will carefully manage the CBO statistics, ensuring that no SQL changes execution plans after it is migrated into production.
Considering the CBO
While we have gone into great detail on the CBO, there is always more to learn as the CBO becomes more powerful (and complex) with each new release of Oracle. The main points of this article include general guidelines for adjusting the behavior of the CBO: