Skip to Main Content

Oracle Database Discussions

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Index range scan vs. full scan descending?

D.VegaMar 13 2012 — edited Apr 11 2012
Hi. I want to understand how index modifications are working here and why. I tried reseaching oficial documentation, but i feel like if I was swimming in a big ocean. Im starting as Oracle DBA, and I would like to understand this oracle behavior. Some clues will be appreciated:

I was dealing with a terrible designed query (and of course, no one wants to modificate the php application who builds it) which generates tons of db_sequential_reads in a huge table, and spends lots of time to execute. The only option that allows me is to handle with the oracle system and/or suggest some hints implement.
I'm not allowed to paste the whole real query, so i changed some names and removed unnecesary lines. DB is 9.2.0.2, all statistics are up to date, and query Its similar like this:
select *  
from	(  
			select 
				a.*, 
				ROWNUM rnum 
			from	(
					select  /*+ FIRST_ROWS (20) */
						ID,
						( select NAME from TABLE_B where TABLE_A.SENDERNAME_ID = TABLE_B.NAME_ID ) SENDERNAME,
						( select NAME from TABLE_B where TABLE_A.RECEIVERNAME_ID = TABLE_B.NAME_ID ) RECEIVERNAME,
					from TABLE_A
					where SENDERNAME_ID like 1234
					and ( select NAME from TABLE_B where TABLE_A.SENDERNAME_ID = TABLE_B.NAME_ID ) like 'Vendor_1234'
					order by ID
					)    
			where ROWNUM <= 20 
		)  
where rnum >= 1;
After analyzing traces and explain plans, I see that the optimizer use an index range scan in the column that is in the where clause.
STAT #1 id=1 cnt=20 pid=0 pos=1 obj=0 op='VIEW  '
STAT #1 id=2 cnt=20 pid=1 pos=1 obj=0 op='COUNT STOPKEY '
STAT #1 id=3 cnt=20 pid=2 pos=1 obj=0 op='VIEW  '
STAT #1 id=4 cnt=20 pid=3 pos=1 obj=0 op='SORT ORDER BY STOPKEY '
STAT #1 id=5 cnt=182388 pid=4 pos=1 obj=30578 op='TABLE ACCESS BY INDEX ROWID TABLE_A '
STAT #1 id=6 cnt=182388 pid=5 pos=1 obj=30665 op='INDEX RANGE SCAN TABLE_A-SENDERNAME_ID_IDX '
STAT #1 id=7 cnt=1 pid=6 pos=2 obj=30570 op='TABLE ACCESS BY INDEX ROWID TABLE_B '
STAT #1 id=8 cnt=1 pid=7 pos=1 obj=30571 op='INDEX UNIQUE SCAN PK_TABLE_B-NAME_ID '
Somehow I figure out (or I readed somewhere) that with large tables joined with small tables it could be worst the use of ranged scans index, so I force the optimizer to use a full scan descending in the PK with the hint INDEX_DESC, and the query speed improves from 309 secs to 0.24 secs. in every executions.
STAT #1 id=1 cnt=20 pid=0 pos=1 obj=0 op='VIEW  '
STAT #1 id=2 cnt=20 pid=1 pos=1 obj=0 op='COUNT STOPKEY '
STAT #1 id=3 cnt=20 pid=2 pos=1 obj=0 op='VIEW  '
STAT #1 id=4 cnt=20 pid=3 pos=1 obj=0 op='FILTER  '
STAT #1 id=5 cnt=20 pid=4 pos=1 obj=30578 op='TABLE ACCESS BY INDEX ROWID TABLE_A '
STAT #1 id=6 cnt=1288 pid=5 pos=1 obj=30579 op='INDEX FULL SCAN DESCENDING PK_TABLE_A-ID '
STAT #1 id=7 cnt=1 pid=4 pos=2 obj=30570 op='TABLE ACCESS BY INDEX ROWID TABLE_B '
STAT #1 id=8 cnt=1 pid=7 pos=1 obj=30571 op='INDEX UNIQUE SCAN PK_TABLE_B-NAME_ID '
Yes, it solves the problem, but I ask myself "why?",.. and I dont have a clue.
I want to have a better answer than "I had lucky and I did a wondering supposition which hit the spot!". I want to understand this for my professional future. Someone can teach me why this worked?

Thanks in advance

elvegaa_esp

Edited by: elvegaa_esp on 13-mar-2012 6:24

Edited by: elvegaa_esp on 13-mar-2012 6:34
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on May 9 2012
Added on Mar 13 2012
9 comments
1,809 views