oracle - How can I get a COUNT(col) ... GROUP BY to use an index? -
i've got table (col1, col2, ...) index on (col1, col2, ...). table has got millions of rows in it, , want run query:
select col1, count(col2) col1 not in (<couple of exclusions>) group col1
unfortunately, resulting in full table scan of table, takes upwards of minute. there way of getting oracle use index on columns return results faster?
edit:
more specifically, i'm running following query:
select owner, count(object_name) all_objects group owner
and there index on sys.obj$
(sys.i_obj2
) indexes owner#
, name
columns; believe should able use index in query, rather full table scan of sys.obj$
i have had chance play around this, , previous comments regarding not in red herring in case. key thing presence of nulls, or rather whether indexed columns have not null constraints enforced.
this going depend on version of database you're using, because optimizer gets smarter each release. i'm using 11gr1 , optimizer used index in cases except one: when both columns null , didn't include not in
clause:
sql> desc big_table name null? type ----------------------------------- ------ ------------------- id number col1 number col2 varchar2(30 char) col3 date col4 number
without not in clause...
sql> explain plan 2 select col4, count(col1) big_table 3 group col4 4 / explained. sql> select * table(dbms_xplan.display) 2 / plan_table_output --------------------------------------------------------------------------------------- plan hash value: 1753714399 ---------------------------------------------------------------------------------------- | id | operation | name | rows | bytes |tempspc| cost (%cpu)| time | ---------------------------------------------------------------------------------------- | 0 | select statement | | 31964 | 280k| | 7574 (2)| 00:01:31 | | 1 | hash group | | 31964 | 280k| 45m| 7574 (2)| 00:01:31 | | 2 | table access full| big_table | 2340k| 20m| | 4284 (1)| 00:00:52 | ---------------------------------------------------------------------------------------- 9 rows selected. sql>
when dobbed not in
clause in, optimizer opted use index. weird.
sql> explain plan 2 select col4, count(col1) big_table 3 col1 not in (12, 19) 4 group col4 5 / explained. sql> select * table(dbms_xplan.display) 2 / plan_table_output --------------------------------------------------------------------------------------- plan hash value: 343952376 ---------------------------------------------------------------------------------------- | id | operation | name | rows | bytes |tempspc| cost (%cpu)| time | ---------------------------------------------------------------------------------------- | 0 | select statement | | 31964 | 280k| | 5057 (3)| 00:01:01 | | 1 | hash group | | 31964 | 280k| 45m| 5057 (3)| 00:01:01 | |* 2 | index fast full scan| big_i2 | 2340k| 20m| | 1767 (2)| 00:00:22 | ---------------------------------------------------------------------------------------- predicate information (identified operation id): plan_table_output ---------------------------------------------------------------------------------------- 2 - filter("col1"<>12 , "col1"<>19) 14 rows selected. sql>
just repeat, in other cases, long 1 of indexed columns declared not nill, index used satisfy query. may not true on earlier versions of oracle, points way forward.
Comments
Post a Comment