I don't believe the hypothesis that "ONLY THE ORDER OF COLUMNS DETERMINE WEATHER INDEX IS USED " can hold true.
What drives the use of the index is based on what is in the select statement and what is in the predicate (and at 7.3 order matters, if you are still using 7.3)
Consider this example. I select two columns, the order of the select statement does not drive index used, but rather which column in the predicate is used:
09:36:10 ORIONCOP@orionssg01:SQL> select distinct order_id, order_no from sfwid_order_desc where order_id > 'new_order';
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=FIRST_ROWS (Cost=29 Card=1 Bytes=
20)
1 0 SORT (UNIQUE NOSORT) (Cost=29 Card=1 Bytes=20)
2 1 INDEX (RANGE SCAN) OF 'SFWID_ORDER_DESC_INDX004' (NON-UN
IQUE) (Cost=3 Card=2 Bytes=40)
09:36:45 ORIONCOP@orionssg01:SQL> select distinct order_id, order_no from sfwid_order_desc where order_no > 'new_order';
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=FIRST_ROWS (Cost=30 Card=1 Bytes=
20)
1 0 SORT (UNIQUE) (Cost=30 Card=1 Bytes=20)
2 1 TABLE ACCESS (BY INDEX ROWID) OF 'SFWID_ORDER_DESC' (Cos
t=4 Card=2 Bytes=40)
3 2 INDEX (RANGE SCAN) OF 'SFWID_ORDER_UNQ_ORDERNO' (UNIQU
E) (Cost=3 Card=2)
09:37:10 ORIONCOP@orionssg01:SQL> select distinct order_no, order_id from sfwid_order_desc where order_no > 'new_order';
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=FIRST_ROWS (Cost=30 Card=1 Bytes=
20)
1 0 SORT (UNIQUE) (Cost=30 Card=1 Bytes=20)
2 1 TABLE ACCESS (BY INDEX ROWID) OF 'SFWID_ORDER_DESC' (Cos
t=4 Card=2 Bytes=40)
3 2 INDEX (RANGE SCAN) OF 'SFWID_ORDER_UNQ_ORDERNO' (UNIQU
E) (Cost=3 Card=2)
09:37:38 ORIONCOP@orionssg01:SQL> select distinct order_no, order_id from sfwid_order_desc where order_id > 'new_order';
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=FIRST_ROWS (Cost=29 Card=1 Bytes=
20)
1 0 SORT (UNIQUE NOSORT) (Cost=29 Card=1 Bytes=20)
2 1 INDEX (RANGE SCAN) OF 'SFWID_ORDER_DESC_INDX004' (NON-UN
IQUE) (Cost=3 Card=2 Bytes=40)
09:38:12 ORIONCOP@orionssg01:SQL> select distinct order_id, order_no from sfwid_order_desc where order_id > 'new_order';
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=FIRST_ROWS (Cost=29 Card=1 Bytes=
20)
1 0 SORT (UNIQUE NOSORT) (Cost=29 Card=1 Bytes=20)
2 1 INDEX (RANGE SCAN) OF 'SFWID_ORDER_DESC_INDX004' (NON-UN
IQUE) (Cost=3 Card=2 Bytes=40)
When I remove the use of a predicate, it will only use 1 index regardless of the order:
09:43:36 ORIONCOP@orionssg01:SQL> select order_no, order_id from sfwid_order_desc;
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=FIRST_ROWS (Cost=6457 Card=693452
Bytes=13869040)
1 0 INDEX (FULL SCAN) OF 'SFWID_ORDER_DESC_INDX004' (NON-UNIQU
E) (Cost=6457 Card=693452 Bytes=13869040)
09:43:51 ORIONCOP@orionssg01:SQL> select order_id, order_no from sfwid_order_desc;
Execution Plan
----------------------------------------------------------
0 SELECT STATEMENT Optimizer=FIRST_ROWS (Cost=6457 Card=693452
Bytes=13869040)
1 0 INDEX (FULL SCAN) OF 'SFWID_ORDER_DESC_INDX004' (NON-UNIQU
E) (Cost=6457 Card=693452 Bytes=13869040)
To answer jmannix's question - turn on trace and experiment.