Search notes:

Oracle: Init parameter _TABLE_SCAN_COST_PLUS_ONE

If _table_scan_cost_plus_one is set to true, the optimizer will increase the estimated cost by one when planning an execution plan involving full table scan or index fast full scan.

Full table scan

drop   table tq84_cost_test;

create table tq84_cost_test (
   dummy number(1)
);

insert into tq84_cost_test values (0);

begin
   dbms_stats.gather_table_stats(user, 'tq84_cost_test');
end;
/

--

explain plan for
select
   *
from
   tq84_cost_test;

select * from dbms_xplan.display(format=>'basic +cost');
--
-- ---------------------------------------------------------
-- | Id  | Operation         | Name           | Cost (%CPU)|
-- ---------------------------------------------------------
-- |   0 | SELECT STATEMENT  |                |     3   (0)|
-- |   1 |  TABLE ACCESS FULL| TQ84_COST_TEST |     3   (0)|
-- ---------------------------------------------------------


--
-- The default value of _table_scan_cost_plus_one is true
-- which causes the cost associated with
-- TABLE ACCESS FULL to be increased by one
-- Setting it to false gives the 'original' value.
-- 
alter session set "_table_scan_cost_plus_one" = false;

explain plan for
select
   *
from
   tq84_cost_test;

select * from table(dbms_xplan.display(format=>'basic +cost'));
--
-- ---------------------------------------------------------
-- | Id  | Operation         | Name           | Cost (%CPU)|
-- ---------------------------------------------------------
-- |   0 | SELECT STATEMENT  |                |     2   (0)|
-- |   1 |  TABLE ACCESS FULL| TQ84_COST_TEST |     2   (0)|
-- ---------------------------------------------------------


-- Revert to default
alter session set "_table_scan_cost_plus_one" = true;

Index full scan fast

create table tq84_tab (
   num  number(3),
   txt  varchar2(100)
);

insert into tq84_tab
select
   trunc(dbms_random.value(0, 1000)),
   rpad('x', 100)
from
   dual connect by level <= 10000;

create index tq84_tab_ix on tq84_tab(num);

begin
   dbms_stats.gather_table_stats(user, 'tq84_tab');
end;
/


alter session set "_table_scan_cost_plus_one" = false;
explain plan for
select
   avg(num) 
from
   tq84_tab;
select * from table(dbms_xplan.display(format=>'basic +cost'));
--
-- ----------------------------------------------------------
-- | Id  | Operation             | Name        | Cost (%CPU)|
-- ----------------------------------------------------------
-- |   0 | SELECT STATEMENT      |             |     6   (0)|
-- |   1 |  SORT AGGREGATE       |             |            |
-- |   2 |   INDEX FAST FULL SCAN| TQ84_TAB_IX |     6   (0)|
-- ----------------------------------------------------------

alter session set "_table_scan_cost_plus_one" = true;
explain plan for
select
   avg(num) 
from
   tq84_tab;
select * from table(dbms_xplan.display(format=>'basic +cost'));
--
-- ----------------------------------------------------------
-- | Id  | Operation             | Name        | Cost (%CPU)|
-- ----------------------------------------------------------
-- |   0 | SELECT STATEMENT      |             |     7   (0)|
-- |   1 |  SORT AGGREGATE       |             |            |
-- |   2 |   INDEX FAST FULL SCAN| TQ84_TAB_IX |     7   (0)|
-- ----------------------------------------------------------

drop   table tq84_tab;

Other observations

In the following script, changing the value of _table_scan_cost_plus_one changes between INDEX FULL SCAN and INDEX FAST FULL SCAN:
create index tq84_cost_test_ix on tq84_cost_test(dummy);

explain plan for
select
   sum(dummy)
from
   tq84_cost_test;

select * from table(dbms_xplan.display(format=>'basic +cost'));
--
-- -----------------------------------------------------------
-- | Id  | Operation        | Name              | Cost (%CPU)|
-- -----------------------------------------------------------
-- |   0 | SELECT STATEMENT |                   |     1   (0)|
-- |   1 |  SORT AGGREGATE  |                   |            |
-- |   2 |   INDEX FULL SCAN| TQ84_COST_TEST_IX |     1   (0)|
-- -----------------------------------------------------------

alter session set "_table_scan_cost_plus_one" = false;
explain plan for
select
   sum(dummy)
from
   tq84_cost_test;

select * from table(dbms_xplan.display(format=>'basic +cost'));
--
-- ----------------------------------------------------------------
-- | Id  | Operation             | Name              | Cost (%CPU)|
-- ----------------------------------------------------------------
-- |   0 | SELECT STATEMENT      |                   |     1   (0)|
-- |   1 |  SORT AGGREGATE       |                   |            |
-- |   2 |   INDEX FAST FULL SCAN| TQ84_COST_TEST_IX |     1   (0)|
-- ----------------------------------------------------------------

See also

The init parameters

Index