Home » RDBMS Server » Performance Tuning » How to avoid full tablescan using group function?
icon6.gif  How to avoid full tablescan using group function? [message #127763] Wed, 13 July 2005 03:36 Go to next message
rgopani
Messages: 15
Registered: June 2005
Location: rupesh_gopani@yahoo.com
Junior Member

Hi,

When I access my table normaly,without group function it does index range scan like this. as there is index on pharmacyid column

SELECT drugauctionid, amount
FROM drugbid Y
WHERE pharmacyid = 142

but when i use group function it does a full tablescan like this..

SELECT drugauctionid, amount
FROM drugbid Y
WHERE pharmacyid = 142
GROUP BY drugauctionid,amount

the execution plan is as follow when it does a full tablescan

Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=FIRST_ROWS (Cost=8 Card=75 Bytes=
750)

1 0 SORT (GROUP BY) (Cost=8 Card=75 Bytes=750)
2 1 TABLE ACCESS (FULL) OF 'DRUGBID' (Cost=4 Card=75 Bytes=7
50)

the value of optimizer_* parameters as as follow.

ALTER session SET OPTIMIZER_INDEX_CACHING=100
ALTER session SET OPTIMIZER_INDEX_COST_ADJ=30
Optimizer mode is first_rows
version is 9.2.0.6

How can I use index range scan even with group function?


[Updated on: Wed, 13 July 2005 03:39]

Report message to a moderator

Re: How to avoid full tablescan using group function? [message #127771 is a reply to message #127763] Wed, 13 July 2005 04:21 Go to previous messageGo to next message
SoporteDBA
Messages: 7
Registered: July 2005
Location: Écija, Sevilla
Junior Member
Hello,

In the cost-based optimized mode (like FIRST_ROWS) ,execution plan depends on many factors, one of then is the size of the table, num rows, ...

So, if your table is too small, this can be a reason of the "table access (full)"

If your table is not too small, you should have to analyze the table/index.

Cardinality of values on column pharmacyid is also very important, if you have a low cardinality (small number of diferent values versus de total number of rows), this can be a reason as well of the "table access (full)".

In the tule-based optimized mode, the group query will take the index:

SELECT /*+ rule */ drugauctionid, amount
FROM drugbid Y
WHERE pharmacyid = 142
GROUP BY drugauctionid,amount

but this should be avoid because of the recomendations of Oracle (not use of rule based optimizer on new releases).

Another thing you could do is to include in the index, the columns drugauctionid and amount if you can allow it.
Re: How to avoid full tablescan using group function? [message #128046 is a reply to message #127763] Thu, 14 July 2005 16:09 Go to previous messageGo to next message
prmoore77
Messages: 18
Registered: July 2005
Location: Cincinnati, Ohio
Junior Member
I couldn't re-create your example, but can offer a general hint if you absolutely need to do this...

Try materializing the keyed-read first BEFORE grouping, like this:

SELECT drugauctionid, amount
FROM
(
SELECT drugauctionid, amount
FROM drugbid Y
WHERE pharmacyid = 142
AND ROWNUM >= 0 /* this line will force materialization */
)
GROUP BY drugauctionid,amount
/

The inner block will have to run first and materialize due to the use of the pseudo-column ROWNUM. That should force a keyed-index read as you desired while maintaining the GROUP BY you desire.

Please give it a try and let me know...

Take care,

Philip
Re: How to avoid full tablescan using group function? [message #128090 is a reply to message #128046] Fri, 15 July 2005 00:04 Go to previous messageGo to next message
d.dineshkumar
Messages: 211
Registered: April 2005
Location: Kolkatta
Senior Member
Hi philip
what is materialization ,as u have mentioned.

Thanks
Dinesh
Re: How to avoid full tablescan using group function? [message #128166 is a reply to message #128090] Fri, 15 July 2005 08:35 Go to previous messageGo to next message
prmoore77
Messages: 18
Registered: July 2005
Location: Cincinnati, Ohio
Junior Member
Hi Dinesh,

Materialization refers to the fact that Oracle must create a temporary structure, a temp table if you will.

When one uses the ROWNUM pseudo-column in a subquery, Oracle cannot merge that query with the outer one because it must first get the result of that query, and then assign a "ROWNUM" to it. If I had omitted the ROWNUM column, the Cost-Based Optimizer would have re-written it to appear like the original one that rgopani posted (it would simplify it) - a technique known as merging. ROWNUM prevents this from occuring.

So if the Cost-Based Optimizer makes weird decisions, as was the case here, you can prevent such anomolies by forcing Oracle to "materialize" your inner result set first, then you can work with that result set like it was a normal table.

Hope this helps, for more info - see Tom Kyte's book - Effective Oracle by Design - he covers it in detail...

Regards,

Philip
Re: How to avoid full tablescan using group function? [message #128265 is a reply to message #127763] Sat, 16 July 2005 11:24 Go to previous messageGo to next message
smartin
Messages: 1803
Registered: March 2005
Location: Jacksonville, Florida
Senior Member
The rownum hint is in general a good one to keep in mind, although you didn't provide enough about your situation to know if it will help. How about trying this. Capture and post to us your session doing the following:

dbms_stats.gather_table_stats(user,'drugbid',cascade=>true,method_opt=>'for all columns size 250');

alter session set optimizer_mode=all_rows;

set timing on

set autotrace on explain statistics;

set echo on;

run your first query (without the group by)

run your second query (with group by)

post all that to us.

In other words, make sure you have current and complete stats on table, index, and histograms. Also, first_rows would be useful in a query without group by and lean towards an index to only get the first few rows. But in your goup by case, you are probably wanting the grand total, meaning all_rows would be more appropriate. But you gotta show us the full queries.

And remember, full scan is not always bad. Speed and resource usage is what matters. Oh and post a describe of your table, as well as a list of all indexes, type of index, and columns in the index. After you post all that we can discuss further.
Re: How to avoid full tablescan using group function? [message #128316 is a reply to message #128166] Sun, 17 July 2005 23:24 Go to previous messageGo to next message
d.dineshkumar
Messages: 211
Registered: April 2005
Location: Kolkatta
Senior Member
Thanks phillip,
Got a good idea.

with regards
dinesh
Re: How to avoid full tablescan using group function? [message #130881 is a reply to message #127763] Wed, 03 August 2005 01:24 Go to previous messageGo to next message
sharan_it
Messages: 140
Registered: July 2005
Location: Chennai
Senior Member
I cant understand merging completely..and i liked to know how it differs of using inline view(with rowid) with normal one..

But i got opposite to rgopani

Normal select statement gives full table scan and group by select statement gives index range scan(pharmacy ID have non unique index)


C2K@FXUT> select * from drugbid;

PHARMACYID DRUGAUCTIONID AMOUNT
---------- ------------- ---------
1 532 7000
2 538 4000
3 5738 3000
4 738 6000
5 79 8000
5 79 8000
5 79 8000
5 79 8000
1 532 7000

9 rows selected.


Execution Plan
----------------------------------------------------------
0
SELECT STATEMENT Optimizer=CHOOSE


1 0
TABLE ACCESS (FULL) OF 'DRUGBID'





C2K@FXUT> SELECT drugauctionid, amount
2 FROM drugbid Y
3 WHERE pharmacyid = 5
4 GROUP BY drugauctionid,amount;

DRUGAUCTIONID AMOUNT
------------- ---------
79 8000


Execution Plan
----------------------------------------------------------
0
SELECT STATEMENT Optimizer=CHOOSE


1 0
SORT (GROUP BY)


2 1
TABLE ACCESS (BY INDEX ROWID) OF 'DRUGBID'


3 2
INDEX (RANGE SCAN) OF 'PHAR_ID' (NON-UNIQUE)


1 SELECT drugauctionid, amount
2 FROM
3 (
4 SELECT drugauctionid, amount
5 FROM drugbid Y
6 WHERE pharmacyid = 5
7 AND ROWNUM >= 0)
8* GROUP BY drugauctionid,amount
C2K@FXUT> /

DRUGAUCTIONID AMOUNT
------------- ---------
79 8000


Execution Plan
----------------------------------------------------------
0
SELECT STATEMENT Optimizer=CHOOSE


1 0
SORT (GROUP BY)


2 1
VIEW


3 2
COUNT


4 3
FILTER


5 4
TABLE ACCESS (BY INDEX ROWID) OF 'DRUGBID'


6 5
INDEX (RANGE SCAN) OF 'PHAR_ID' (NON-UNIQUE)







Re: How to avoid full tablescan using group function? [message #130882 is a reply to message #127763] Wed, 03 August 2005 01:28 Go to previous message
sharan_it
Messages: 140
Registered: July 2005
Location: Chennai
Senior Member
Even if i omit rownum in inline view i get index range scan

1 SELECT drugauctionid, amount
2 FROM
3 (
4 SELECT drugauctionid, amount
5 FROM drugbid Y
6 WHERE pharmacyid =5)
7* GROUP BY drugauctionid,amount
C2K@FXUT> /

DRUGAUCTIONID AMOUNT
------------- ---------
79 8000


Execution Plan
----------------------------------------------------------
0
SELECT STATEMENT Optimizer=CHOOSE


1 0
SORT (GROUP BY)


2 1
TABLE ACCESS (BY INDEX ROWID) OF 'DRUGBID'


3 2
INDEX (RANGE SCAN) OF 'PHAR_ID' (NON-UNIQUE)

Previous Topic: undo management
Next Topic: Best way to figure out bad sql in the database
Goto Forum:
  


Current Time: Mon Nov 28 05:00:34 CST 2022