Oracle FAQ Your Portal to the Oracle Knowledge Grid
HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US
 

Home -> Community -> Usenet -> c.d.o.server -> Re: Query performance

Re: Query performance

From: Rniemic <rniemic_at_aol.com>
Date: 2000/04/11
Message-ID: <20000411124356.10471.00000853@ng-bk1.aol.com>

Here are some ideas cut from chapter 1 of my book on timing things. Basically, you can time things by tracing them in addition to setting the timing on (I appologize that I can't line everything up given this text window). The notes for timing, trace and explain are below.

Thanks,
Rich Niemiec, Oracle Performance Tuning Tips and Techniques; Oracle Press http://www.amazon.com/exec/obidos/ASIN/0078824346/o/qid=928871379/sr=2-1/1 03-5004516-2917402

From chapter 1:
What you need to know before you tune your system

The first thing you need to know is the data. The volume of data and the distribution of data will affect how you tune individual queries. You also need to have a "shopping cart" full of tuning methods to try. Multiple approaches must be made to cover all types of queries. A single method of tuning or a single tuning product is NOT enough. You also need to know where the system is slow. Many DBAs and developers spend endless hours finding problem queries instead of asking the users of the system. Users will almost always be happy to volunteer this information. You also need to network with other developers that work on a similar system. Sharing information at user groups is a great way to network.

Setting Timing On

To tell whether or not you are improving the performance of a query you must have a benchmark or way to time the query. While a stopwatch can be used, the "set timing" feature in SQLPLUS is an excellent way to time queries. Unfortunately, the timing is affected by others on the system, but those of us who tune seriously usually do it at 2am. Use the following SQL statements for the SET TIMING feature.

SQL> SET TIMING ON

SQL> 	select 	count(name)  
	from	emp7
	where 	name = 'branches';

Output

COUNT(NAME)



100

Elapsed: 00:00:00.84 (HOURS:MINUTES:SECONDS)

Setting Autotrace On

An even better way for measuring the performance of queries (in SQLPLUS 3.3 and later) is to use the AUTOTRACE command. Use the following SQL statements for the AUTOTRACE feature.

SQL> SET AUTOTRACE ON

SQL> 	select 	count(name)  
	from	emp7
	where 	name = 'branches';

Output

COUNT(NAME)



100

Execution Plan

----------------------------------------------------------       0      SELECT
STATEMENT Optimizer=CHOOSE                                   1    0   SORT

(AGGREGATE) 2 1 INDEX (RANGE SCAN) OF 'EMP7_I1'
(NON-UNIQUE)
Statistics 0 recursive calls 0 db block gets 1 consistent gets 1 physical reads 0 redo size 223 bytes sent via SQL*Net to client 274 bytes recd via SQL*Net from client 2 SQL*Net roundtrips to/from client 1 sorts (memory) 0 sorts (disk) 1 rows processed

Tracing a single session:

select sid, serial#
from v$session
where username = ‘SCOTT’;

SID SERIAL#
---------- ----------

         9 190
1 row selected.

execute dbms_system.set_sql_trace_in_session(9,190,TRUE); PL/SQL procedure successfully completed.

The Oracle Trace Utility (See Chapter 6 for more information on trace and explain plan)
In order to tune queries you must be able to find problem queries and analyze the potential problems with those queries. The Oracle Trace utility is used to measure timing statistics for a given query, batch process (with multiple queries) or an entire system. It is a fast method of finding where potential bottlenecks on the system reside. It also has an option to run an explain plan to generate the optimizers path for executing a query. This section will focus briefly on how to use this powerful tool. Chapter xx is completely devoted to Trace and Explain.

Simple Steps for Trace with a Simple Query:

  1. Set the following INIT.ORA Parameters: TIMED_STATISTICS = TRUE MAX_DUMP_FILE_SIZE = 2000000 (Not 2M) USER_DUMP_DEST = /oracle6/rich_trc
  2. Enable TRACE for a SQLPLUS session: SQL> ALTER SESSION SET SQL_TRACE TRUE;
3a. Run the query to be TRACED:
SELECT 	TABLE_NAME, OWNER,
		INITIAL_EXTENT, UNIQUENESS
FROM 	IND2 
WHERE 	OWNER || '' = 'SCOTT' ; 

(Note: Index on "OWNER" suppressed)

4. Disable TRACE for the SQLPLUS same session:

SQL>ALTER SESSION SET SQL_TRACE FALSE; 5. You can ALSO Enable TRACE for all sessions (NOT SUGGESTED):

        SQL_TRACE = TRUE (In the INIT.ORA)

After running TRACE your output file may be something like: 5_19554.trc

6. Run tkprof to put the TRACE file into "readable" format:

tkprof 5_19554.trc rich2.prf explain=system/manager

The TKPROF utility translates the trace file generated by the SQL trace facility to a readable format. You can run TKPROF against a trace file that you have previously created, or you can run it while the program that is creating the trace file is still running. Options for tkprof are listed below.

7a. The output of the file "rich2.prf" (with the index suppressed):


SELECT 	TABLE_NAME, OWNER,
		INITIAL_EXTENT, UNIQUENESS
FROM 	IND2 
WHERE 	OWNER = 'SCOTT';

            count     cpu    elap    phys      cr     cur    rows
Parse:       1        1          2         0          0       0
Execute:   1        0          0         0          0       2        0
Fetch:       2       69      113      142      430      0       36

Execution plan: (No Index Used)
TABLE ACCESS (FULL) OF 'IND2' 7b. Re-Run the query to be TRACED now using the index:

SELECT 	TABLE_NAME, OWNER,
		INITIAL_EXTENT, UNIQUENESS
FROM 	IND2 
WHERE 	OWNER = 'SCOTT' ;  (The index on "OWNER" is not suppressed)

The output of the file "rich2.prf":


SELECT 	TABLE_NAME, OWNER, 
		INITIAL_EXTENT, UNIQUENESS 
FROM 	IND2 
WHERE 	OWNER = 'SCOTT' ;

            count     cpu    elap    phys      cr     cur    rows
Parse:       2         0        0         0         0          0
Execute:   2         0        0         0         0          0         0
Fetch:       4         6        6         0       148        0       72

Execution plan: (Index Used)
TABLE ACCESS (BY ROWID) OF 'IND2'
  INDEX (RANGE SCAN) OF 'IND2_1' (NON-UNIQUE) Tip: A traced query with a large number of physical reads usually indicates a missing index. The "phys" column indicates the physical reads (usually where an index is not used) and the "cr" added to the "cur" columns indicates the memory reads (usually reads where an index is being used).

Using Explain Plan (See Chapter xx for more information)

The Explain Plan command allows a developer to view the query execution plan that the Oracle optimizer will use to execute an SQL statement. This command is very helpful in improving performance of SQL statements, since it does not actually execute the SQL statement, it only outlines the plan to use and inserts this execution plan in an Oracle table.

Why use Explain without TRACE?
* The Statement is NOT executed, it only shows what will happen if the statement is executed.

When to use Explain without TRACE:
* When the query will take exceptionally long to run.

How do I use Explain by itself?

  1. Find the script; it is usually in $ORACLE_HOME/rdbms/admin.

· "utlxplan.sql"

2. Execute the script xplainpl.sql in SQLPLUS:

        SQL>@utlplan (In V7)
(This creates the PLAN_TABLE for the user executing the script)

3a. Run Explain Plan for the query to be optimized:

EXPLAIN PLAN FOR

SELECT 	CUSTOMER_NUMBER
FROM   	CUSTOMER
WHERE  	CUSTOMER_NUMBER = 111;

Explained.

3b. Run Explain Plan for the query to be optimized (Using a tag for the statement):
EXPLAIN PLAN
SET STATEMENT_ID = 'CUSTOMER' FOR

SELECT 	CUSTOMER_NUMBER
FROM   	CUSTOMER
WHERE  	CUSTOMER_NUMBER = 111;


4. Select the output from the PLAN_TABLE:

select	operation, options, object_name, 
	id, parent_id, position
from 	plan_table
where 	statement_id = 'CUSTOMER';

Operation         	Options       Object_Name     ID    Parent
----------------   	-----------       ------------------   ---    --------
Select Statement					0
Table Access   	By Rowid      Customer          1    
Index               	Range Scan    CUST_IDX      2        1



Tip: Use EXPLAIN instead of TRACE so that you don't have to wait for the query to run. EXPLAIN will show the path of a query without actually running the query. Use TRACE only for multi-query batch jobs to find out which of the many queries in the batch job is slow.

Explain Plan - Read it top to bottom or bottom to top?

Actually, it depends on how you write the query that retrieves the information from the PLAN_TABLE table. That is probably why many people differ on which way to read the result (all of them may be correct). Below, I give an example with the order of execution based on the query that retrieves the information..

Delete From Plan_Table;
Explain Plan
  Set Statement_Id = 'SQL1' For
select To_Char(SysDate, 'MM/DD/YY HH:MM AM'),

       To_Char((Trunc((SysDate -4 -1), 'day') +1), 'DD-MON-YY'), from bk, ee
where bk_shift_date >= To_Char((Trunc(( SysDate - 4 - 1),

                                'day') + 1), 'dd-mon-yy')     
  and bk_shift_date <= To_Char((SysDate - 4), 'dd-mon-yy')   and bk_empno = ee_empno(+)
  and SubStr(ee_hierarchy_code, 1, 3) in

               ('PNA', 'PNB', 'PNC', 'PND', 'PNE', 'PNF') order by ee_job_group, bk_empno, bk_shift_date /

Select LPad(' ', 2*(Level-1)) || Level || '.' || Nvl(Position,0)||

   ' ' || Operation || ' ' || Options || ' ' || Object_Name || ' ' ||    Object_Type || ' ' || Decode(id, 0, Statement_Id ||' Cost = ' ||    Position) || Other || ' ' || Object_Node    "Query Plan"
From Plan_Table
Start with id = 0 And Statement_Id = 'SQL1' Connect By Prior Id = Parent_Id
And Statement_Id = 'SQL1'
/

Query Plan




1.0 SELECT STATEMENT SQL1 Cost =
	2.1 SORT ORDER BY
		3.1 FILTER
			4.1 NESTED LOOPS OUTER
				5.1 TABLE ACCESS BY ROWID BK
					6.1 INDEX RANGE SCAN I_BK_06 NON-UNIQUE
				5.2 TABLE ACCESS BY ROWID EE
					6.1 INDEX UNIQUE SCAN I_EE_01 UNIQUE

Reading the Explain Plan

Using the explain plan above I will explain the steps. Each step is identified by the number on the left. I will go in the order in which they are executed.

Step	Action
6.1	This is the index range scan of I_BK_06. This is the first step. This
index is on the BK_SHIFT_DT column. This step performs a scan of this index to get produce a list of row numbers that fall between the two dates.
5.1	Retrieve the rows from the BK table.
6.1	Scan of the I_EE_01 index. This index is on the EE_EMPNO column. Using
the BK_EMPNO retrieved from the previous step, this index is scan to retrieve the rowids to produce a list of the EE_EMPNO's that match the BK_EMPNO's.
5.2	Retrieve the rows from the EE table.
4.1	Nested loop. The two lists are joined, producing one list.
3.1	Filter. The rest of the conditions of the where clause are applied.
2.1	Sort Order By. The remaining rows are sorted according to the order by
clause.
1.0	This tells what type of statement it is.


Tip: Whether the Explain Plan is read from top to bottom or from the bottom to the top is dependent entirely on the query used to select information from the PLAN_TABLE. Both methods of reading the query may be correct, given the query selecting the information is correctly structured.. Received on Tue Apr 11 2000 - 00:00:00 CDT

Original text of this message

HOME | ASK QUESTION | ADD INFO | SEARCH | E-MAIL US