Вы находитесь на странице: 1из 7

Remove unnecessary large-table full-table scans Cache small-table full-table scans Verify optimal index usage Materialize your

aggregations and summaries for static tables

Remove unnecessary large-table full-table scansUnnecessary 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. 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 scansIn 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 Oracle8 and beyond, a small table can be cached by forcing it into the KEEP pool. Verify optimal index usageOracle sometimes has a choice of indexes, and the tuning professional must examine each index and ensure that Oracle is using the proper index. Materialize your aggregations and summaries for static tables - One features of the Oracle 10g SQLAccess advisor is recommendations for new indexes and suggestions for materialized views. Materialized views pre-join tables and presummarize data, a real silver bullet for data mart reporting databases where the data is only updated daily. Again, see the book "Oracle Tuning: The Definitive Reference", for complete details on SQL tuning with materialized views.

EXPLAIN PLAN Usage


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. Interpretation of the execution plan is beyond the scope of this article. Plan Table

AUTOTRACE - The Easy Option? EXPLAIN PLAN Statement ID

Related articles. DBMS_XPLAN : Display Oracle Execution Plans

Plan Table
The explain plan process stores data in the PLAN_TABLE. This table can be located in the current schema or a shared schema and is created using in SQL*Plus as follows: SQL> CONN sys/password AS SYSDBA Connected SQL> @$ORACLE_HOME/rdbms/admin/utlxplan.sql SQL> GRANT ALL ON sys.plan_table TO public; SQL> CREATE PUBLIC SYNONYM plan_table FOR sys.plan_table;

AUTOTRACE - The Easy Option?


Switching on the AUTOTRACE parameter in SQL*Plus causes an explain to be performed on every query. SQL> SQL> 2 3 4 SET AUTOTRACE ON SELECT * FROM emp e, dept d WHERE e.deptno = d.deptno AND e.ename = 'SMITH'; ENAME JOB MGR HIREDATE SAL

EMPNO COMM ------------------DEPTNO ---------7369 20

---------- --------- ---------- --------- ---------DEPTNO ---------SMITH 20 DNAME LOC -------------- ------------CLERK 7902 17-DEC-80 RESEARCH DALLAS

800

Execution Plan ---------------------------------------------------------0 SELECT STATEMENT Optimizer=CHOOSE 1 0 NESTED LOOPS 2 1 TABLE ACCESS (FULL) OF 'EMP' 3 1 TABLE ACCESS (BY INDEX ROWID) OF 'DEPT' 4 3 INDEX (UNIQUE SCAN) OF 'PK_DEPT' (UNIQUE)

Statistics ---------------------------------------------------------81 recursive calls 4 db block gets 27 consistent gets 0 physical reads 0 redo size 941 bytes sent via SQL*Net to client 425 bytes received via SQL*Net from client 2 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed SQL>

This is a relatively easy way to get the execution plan but there is an issue. In order to get the execution plan the statement must be run to completion. If the query is particularly inefficient and/or returns many rows, this may take a considerable time. At first glance, using the TRACEONLY option of AUTOTRACE seems to remove this issue, but this option merely suppresses the output of the query data, it doesn't prevent the statement being run. As such, long running queries will still take a long time to complete, but they will not present their data. The following example show this in practice. CREATE OR REPLACE FUNCTION pause_for_secs(p_seconds IN NUMBER) RETURN NUMBER A BEGIN DBMS_LOCK.sleep(p_seconds); RETURN p_seconds; END; / Function created. SQL> SET TIMING ON SQL> SET AUTOTRACE ON SQL> SELECT pause_for_secs(10) FROM DUAL; PAUSE_FOR_SECS(10) -----------------10 1 row selected. Elapsed: 00:00:10.28 Execution Plan ---------------------------------------------------------Plan hash value: 1550022268

-----------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -----------------------------------------------------------------------| 0 | SELECT STATEMENT | | 1 | | 2 (0)| 00:00:01 | | 1 | FAST DUAL | | 1 | | 2 (0)| 00:00:01 | -----------------------------------------------------------------------Statistics ---------------------------------------------------------189 recursive calls 0 db block gets 102 consistent gets 0 physical reads 0 redo size 331 bytes sent via SQL*Net to client 332 bytes received via SQL*Net from client 4 SQL*Net roundtrips to/from client 13 sorts (memory) 0 sorts (disk) 1 rows processed SQL> SET AUTOTRACE TRACEONLY SQL> SELECT pause_for_secs(10) FROM DUAL; 1 row selected. Elapsed: 00:00:10.26 Execution Plan ---------------------------------------------------------Plan hash value: 1550022268 -----------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | -----------------------------------------------------------------------| 0 | SELECT STATEMENT | | 1 | | 2 (0)| 00:00:01 | | 1 | FAST DUAL | | 1 | | 2 (0)| 00:00:01 | -----------------------------------------------------------------------Statistics

---------------------------------------------------------0 recursive calls 0 db block gets 0 consistent gets 0 physical reads 0 redo size 331 bytes sent via SQL*Net to client 332 bytes received via SQL*Net from client 4 SQL*Net roundtrips to/from client 0 sorts (memory) 0 sorts (disk) 1 rows processed SQL>

The query takes the same time to return (about 10 seconds) whether the TRACEONLY option is used or not. If the TRACEONLY option prevented the query running, you would expect it to return instantly, like an EXPLAIN PLAN. The solution to this is to use the TRACEONLY EXPLAIN option, which only performs the EXPLAIN PLAN, rather than running the statement.

EXPLAIN PLAN
The EXPLAIN PLAN method doesn't require the query to be run, greatly reducing the time it takes to get an execution plan for long-running queries compared to AUTOTRACE. First the query must be explained: SQL> 2 3 4 5 EXPLAIN PLAN FOR SELECT * FROM emp e, dept d WHERE e.deptno = d.deptno AND e.ename = 'SMITH';

Explained. SQL>

Then the execution plan displayed: SQL> @$ORACLE_HOME/rdbms/admin/utlxpls.sql Plan Table ------------------------------------------------------------------------------| Operation | Name | Rows | Bytes| Cost | Pstart| Pstop |

------------------------------------------------------------------------------| SELECT STATEMENT | | | | | | | | NESTED LOOPS | | | | | | | | TABLE ACCESS FULL |EMP | | | | | | | TABLE ACCESS BY INDEX RO|DEPT | | | | | | | INDEX UNIQUE SCAN |PK_DEPT | | | | | | ------------------------------------------------------------------------------8 rows selected. SQL>

For parallel queries use the utlxplp.sql script instead of utlxpls.sql.

Statement ID
If multiple people are accessing the same plan table, or you would like to keep a history of the execution plans you should use the STATEMENT_ID. This associates a user specified ID with each plan which can be used when retrieving the data. SQL> 2 3 4 5 EXPLAIN PLAN SET STATEMENT_ID = 'TIM' FOR SELECT * FROM emp e, dept d WHERE e.deptno = d.deptno AND e.ename = 'SMITH';

Explained. SQL> @explain.sql TIM PLAN OBJECT_NAME BYTES COST PARTITION_START PARTITION_STOP -------------------------------------- ------------------- ----- --------------- --------------Select Statement 57 4 1.1 Nested Loops 57 4 2.1 Table Access (Full) EMP 37 3 2.2 Table Access (By Index Rowid) DEPT 20 1 3.1 Index (Unique Scan) PK_DEPT 0 OBJECT_TYPE ---------------

TABLE TABLE INDEX (UNIQUE)

5 rows selected. SQL> By default the Oracle scripts do not accept a statement_id parameter. You can easily modify the scripts or you can use the script listed under DBA Scripts on this site. For more information see:

4.What is the difference between a hot backup and a cold backup and the benefits associated with each? A hot backup is basically taking a backup of the database while it is still up and running and it must be in archive log mode. A cold backup is taking a backup of the database while it is shut down and does not require being in archive log mode. Benefits: The benefit of taking a hot backup is that the database is still available for use while the backup is occurring and you can recover the database to any ball in time. The benefit of taking a cold backup is that it is typically easier to administer the backup and recovery process. In addition, since you are taking cold backups the database does not require being in archive log mode and thus there will be a slight performance gain as the database is not cutting archive logs to disk.

Вам также может понравиться