It is not entirely clear what you are saying, but I think you are saying "if we have a where clause with six AND'ed predicates, and 4 of them use things we 'conventionally think - we should index' and two of them use these NOT IN or whatever constructs, the index should only contain the four fields".
Maybe, maybe not. "IT DEPENDS" (one of two answers to any technical question, the other being "why?")
select a, b, c, d, x, y, z
from t
where a = 5 and b = 10 and c = 15 and d = 20 and x not in (1,2) and y <> 42;
would it make sense to index (a,b,c,d,x,y) - sure, it could, it might even make sense to index (a,b,c,d,x,y,z)
The reason - to avoid hitting the table when not necessary (a,b,c,d,x,y) can do that. If there are 1,000,000 records out of 100,000,000 where "a = 5 and b = 10 and c = 15 and d = 20" is true, but out of that 1,000,000 only 2 are such that "x not in (1,2) and y <> 42" is true - we might want to discover that before hitting the table 1,000,000 times. We can answer the where clause against the INDEX instead of banging on the table 1,000,000 times to see what x and y are.
And if you add Z, we can avoid the table entirely (wouldn't make sense in my example necessarily because we only visit it twice, but if out of the 1,000,000 times - we found 500,000 hits for the x/y predicate - we might consider adding Z to the index as well)
See the progression of plans in the following:
autotrace traceonly explain
ops$tkyte%ORA10GR2> create index t_idx on t(a,b,c,d);
Index created.
ops$tkyte%ORA10GR2> select a,b,c,d,x,y,z from t where a = 5 and b = 10 and c = 15 and d = 20 and x not in (1,2) and y <> 42;
Execution Plan
----------------------------------------------------------
Plan hash value: 470836197
------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU
------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 91 | 1 (0
|* 1 | TABLE ACCESS BY INDEX ROWID| T | 1 | 91 | 1 (0
|* 2 | INDEX RANGE SCAN | T_IDX | 1 | | 1 (0
------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("X"<>1 AND "X"<>2 AND "Y"<>42)
2 - access("A"=5 AND "B"=10 AND "C"=15 AND "D"=20)
<b>Hit index to evaluate a,b,c,d - go to table to evaluate x,y and pick up z</b>
ops$tkyte%ORA10GR2> drop index t_idx;
Index dropped.
ops$tkyte%ORA10GR2> create index t_idx on t(a,b,c,d,x,y);
Index created.
ops$tkyte%ORA10GR2> select a,b,c,d,x,y,z from t where a = 5 and b = 10 and c = 15 and d = 20 and x not in (1,2) and y <> 42;
Execution Plan
----------------------------------------------------------
Plan hash value: 470836197
------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU
------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 91 | 0 (0
| 1 | TABLE ACCESS BY INDEX ROWID| T | 1 | 91 | 0 (0
|* 2 | INDEX RANGE SCAN | T_IDX | 1 | | 0 (0
------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("A"=5 AND "B"=10 AND "C"=15 AND "D"=20)
filter("X"<>1 AND "X"<>2 AND "Y"<>42)
<b>hit index to evaluate a,b,c,d and then filter on x,y and THEN hit table to pick up Z</b>
ops$tkyte%ORA10GR2> drop index t_idx;
Index dropped.
ops$tkyte%ORA10GR2> create index t_idx on t(a,b,c,d,x,y,z);
Index created.
ops$tkyte%ORA10GR2> select a,b,c,d,x,y,z from t where a = 5 and b = 10 and c = 15 and d = 20 and x not in (1,2) and y <> 42;
Execution Plan
----------------------------------------------------------
Plan hash value: 2946670127
------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time
------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 91 | 0 (0)| 00:00:01
|* 1 | INDEX RANGE SCAN| T_IDX | 1 | 91 | 0 (0)| 00:00:01
------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - access("A"=5 AND "B"=10 AND "C"=15 AND "D"=20)
filter("X"<>1 AND "X"<>2 AND "Y"<>42)
<b>just hit the index, no table</b>
ops$tkyte%ORA10GR2> set autotrace off