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

Home -> Community -> Mailing Lists -> Oracle-L -> SQL Query tuning help

SQL Query tuning help

From: DENNIS WILLIAMS <DWILLIAMS_at_LIFETOUCH.COM>
Date: Tue, 10 Sep 2002 13:12:39 -0500
Message-Id: <22528.293360@fatcity.com>


I am trying to tune a SQL query on Oracle 8.1.6. I have tried several optimizations, but
so far have made no improvements. I would appreciate any suggestions.

SELECT am.lid, am.name
FROM am, so, sa
WHERE so.lid = am.lid

AND so.key_ = sa.so_key
AND am.active = 1
AND so.code = 11
AND sa.ret = 'SB'

ORDER BY am.name

Tables:

   am - 250,000 rows, 220,000 rows have active = 1, the others are 0.    so - 1.3 million rows, lid has 250,000 distinct values, key_ is unique,

             code has 12 values, evenly distributed.    sa - 1.3 million rows, ret has 281 values, fairly evenly distributed. so_key is pretty unique.

Now, you'll probably say there is essentially a 1-1 relationship between so and sa. You are right, but the developer insists this flexibility is essential.

The query executes in 16 seconds and returns 185 rows. This is felt to be too slow for an online lookup screen.

                explain plan results:

		SELECT STATEMENT   Cost = 2955
		  SORT ORDER BY
		    HASH JOIN
		      HASH JOIN
		        TABLE ACCESS FULL SA
		        TABLE ACCESS FULL SO
		      TABLE ACCESS FULL AM

Here is what I've tried so far:

Using hints to force Oracle to use indexes.

Query Plan




SELECT STATEMENT Cost = 62031
  SORT AGGREGATE
    NESTED LOOPS
      HASH JOIN
        TABLE ACCESS BY INDEX ROWID SA
          INDEX FULL SCAN SO_KEY3
        TABLE ACCESS BY INDEX ROWID SO
          INDEX RANGE SCAN PRG_CODE3
      TABLE ACCESS BY INDEX ROWID AM
        INDEX UNIQUE SCAN LID6       

Timing result 25 minutes

Next I tried creating new indexes that combine both the accessing column as well as the retrieved column, thinking that Oracle could get the result from the index block and not need to retrieve the data block.

      create index test1 on am (lid, active);
      create index test2 on sa (so_key, code);

SELECT STATEMENT Cost = 2951
  SORT AGGREGATE
    HASH JOIN

      HASH JOIN
        INDEX FULL SCAN TEST2
        TABLE ACCESS FULL SO
      TABLE ACCESS BY INDEX ROWID AM
        INDEX RANGE SCAN TEST1
                              

Hinting so Oracle will use the new indexes, for one table Oracle uses the index only and for the other table, Oracle hits both the index and table itself. Response time is slightly longer than the original query. At this point I'm fresh out of ideas, so any ideas would be appreciated. Thanks.  

Dennis Williams
DBA Received on Tue Sep 10 2002 - 13:12:39 CDT

Original text of this message

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