GROUP BY doesn't use index without predicate - why?
982092Dec 28 2012 — edited Dec 30 2012Hi - I think this is pretty basic question, but I'm stumped. It seems that unless I use a WHERE clause the index is not used. But by using a where clause - even though it doesn't exclude any records - the index is used. Perhaps this is just how the engine works, but it makes no sense to me. Does anyone have insight?
We are running 11.2.0.1
Situation:
I have a table with 6million rows with recent stats, etc. This table has activity events. One column in this table is DAY which contains a number between 1 and 31 representing day of the month. This column is indexed.
Currently the table only includes data from a single month.
This query does not use the index even with index hint and has a cost of 296649 in Explain plan with FULL as the access option for the table:
select
day, count(*)
from archive.log_usagelogs
group by day;
This query uses the index with a FAST FULL SCAN and has explain plan cost of 4710.
select
day, count(*)
from archive.log_usagelogs
where day between 1 and 31
group by day;
Both return the same results. The 2nd runs much faster than the first.
I ran both with /*+gather_plan_statistics*/ and here are the results:
SQL_ID 5hukqw3822vq8, child number 0
-------------------------------------
select /*+gather_plan_statistics*/ day, count(*) from
archive.log_usagelogs group by day
Plan hash value: 3127609364
-------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
-------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 14 |00:00:09.31 | 1093K| | | |
| 1 | HASH GROUP BY | | 1 | 13 | 14 |00:00:09.31 | 1093K| 1135K| 1135K| 1232K (0)|
| 2 | TABLE ACCESS FULL| LOG_USAGELOGS | 1 | 6526K| 6526K|00:00:22.19 | 1093K| | | |
-------------------------------------------------------------------------------------------------------------------------
___________
SQL_ID 53s7zqhr5zymv, child number 0
-------------------------------------
select /*+gather_plan_statistics*/ day, count(*) from
archive.log_usagelogs where day between 1 and 30 group by day
Plan hash value: 1799032578
--------------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | OMem | 1Mem | Used-Mem |
--------------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | 13 |00:00:04.06 | 17335 | | | |
| 1 | HASH GROUP BY | | 1 | 13 | 13 |00:00:04.06 | 17335 | 1135K| 1135K| 5126K (0)|
|* 2 | INDEX FAST FULL SCAN| IDX_USAGELOGS_DAY | 1 | 6526K| 6526K|00:00:11.37 | 17335 | | | |
--------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(("DAY">=1 AND "DAY"<=30))