Do you need to create an index for fields of group by fields in an Oracle database?
For example:
select *
from some_table
where field_one is not null and field_two = ?
group by field_three, field_four, field_five
I was testing the indexes I created for the above and the only relevant index for this query is an index created for field_two. Other single-field or composite indexes created on any of the other fields will not be used for the above query. Does this sound correct?
No. You don't need to, in the sense that a query will run irrespective of whether any indexes exist or not. Indexes are provided to improve query performance.
It can, however, help; but I'd hesitate to add an index just to help one query, without thinking about the possible impact of the new index on the database.
Not always. Often a GROUP BY will require Oracle to perform a sort (but not always); and you can eliminate the sort operation by providing a suitable index on the column(s) to be sorted.
Whether you actually need to worry about the GROUP BY performance, however, is an important question for you to think about.
It could be correct, but that would depend on how much data you have. Typically I would create an index for the columns I was using in a GROUP BY, but in your case the optimizer may have decided that after using the field_two index that there wouldn't be enough data returned to justify using the other index for the GROUP BY.
No, this can be incorrect.
If you have a large table,
Oracle
can prefer deriving the fields from the indexes rather than from the table, even there is no single index that covers all values.In the latest article in my blog:
NOT IN
vs.NOT EXISTS
vs.LEFT JOIN / IS NULL
:Oracle
, there is a query in which
Oracle
does not use full table scan but rather joins two indexes to get the column values:The plan is:
As you can see, there is no
TABLE SCAN
ont_left
here.Instead,
Oracle
takes the indexes onid
andvalue
, joins them onrowid
and gets the(id, value)
pairs from the join result.Now, to your query:
First, it will not compile, since you are selecting
*
from a table with aGROUP BY
clause.You need to replace
*
with expressions based on the grouping columns and aggregates of the non-grouping columns.You will most probably benefit from the following index:
, since it will contain everything for both filtering on
field_two
, sorting onfield_three, field_four, field_five
(useful forGROUP BY
) and making sure thatfield_one
isNOT NULL
.