Search notes:

Oracle SQL Plan operation BITMAP INDEX SINGLE VALUE

create table tq84_bm (
   flg number(1) not null,
   val number,
   txt varchar2(50)
);

create bitmap index tq84_bm_ix on tq84_bm(flg);

explain plan for
select
   val,
   txt
from
   tq84_bm
where
   flg = 1;

select * from table(dbms_xplan.display(format=>'basic'));
--
-- ----------------------------------------------------------
-- |   0 | SELECT STATEMENT                    |            |
-- |   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| TQ84_BM    |
-- |   2 |   BITMAP CONVERSION TO ROWIDS       |            |
-- |   3 |    BITMAP INDEX SINGLE VALUE        | TQ84_BM_IX |
-- ----------------------------------------------------------

Partitioned table / local index

create table tq84_tab_part (
   id     number(5),
   val    number(5,1),
   txt    varchar2(10),
   grp    char(1)  not null check (grp in ('A', 'B', 'C')),
   --
   constraint tq84_tab_part_pk primary key (id)
)
partition by list (grp) (
   partition tq84_list_partition_A values ('A'),
   partition tq84_list_partition_B values ('B'),
   partition tq84_list_partition_C values ('C')
);

begin
   dbms_random.seed(42);
end;
/

insert into tq84_tab_part
select
   level,
   round(dbms_random.value(0, 1000), 1),
   case round(dbms_random.value, 4)
        when 0.0111 then 'x'
        when 0.0222 then 'y'
        when 0.0333 then 'z'
        else chr(ascii('a') + dbms_random.value(0, 23))
   end,
   chr(ascii('A') + dbms_random.value(0, 3))
from
   dual connect by level <= 30000;


create bitmap index tq84_tab_part_ix_bmp on tq84_tab_part(txt) local;

begin
   dbms_stats.gather_table_stats(
      user,
     'tq84_tab_part',
      method_opt => 'for columns txt size 26' -- size 26: Make sure histograms are created
   );
end;
/

explain plan for
   select
      val,
      txt,
      grp
   from
      tq84_tab_part
   where
      grp in ('A', 'B')      and
      txt in ('x', 'y', 'z')
;

select * from table(dbms_xplan.display(format=>'typical -bytes -cost'));
--
-- ---------------------------------------------------------------------------------------------------------------
-- | Id  | Operation                                   | Name                 | Rows  | Time     | Pstart| Pstop |
-- ---------------------------------------------------------------------------------------------------------------
-- |   0 | SELECT STATEMENT                            |                      |     1 | 00:00:01 |       |       |
-- |   1 |  PARTITION LIST INLIST                      |                      |     1 | 00:00:01 |KEY(I) |KEY(I) |
-- |   2 |   INLIST ITERATOR                           |                      |       |          |       |       |
-- |   3 |    TABLE ACCESS BY LOCAL INDEX ROWID BATCHED| TQ84_TAB_PART        |     1 | 00:00:01 |KEY(I) |KEY(I) |
-- |   4 |     BITMAP CONVERSION TO ROWIDS             |                      |       |          |       |       |
-- |*  5 |      BITMAP INDEX SINGLE VALUE              | TQ84_TAB_PART_IX_BMP |       |          |KEY(I) |KEY(I) |
-- ---------------------------------------------------------------------------------------------------------------
--  
-- Predicate Information (identified by operation id):
-- ---------------------------------------------------
--  
--    5 - access("TXT"='x' OR "TXT"='y' OR "TXT"='z')

drop   table tq84_tab_part;

Combine BITMAP INDEX SINGLE VALUE with BITMAP OR

BITMAP INDEX SINGLE VALUE can perfectly be combined with BITMAP OR:
create table tq84_bitmap_or (
    id       integer,
    val      number(7,2),
    flg_1    varchar2(10),
    flg_2    varchar2(10),
    payload  varchar2(2222)
);
 
create bitmap index tq84_bitmap_or_ix_1 on tq84_bitmap_or(flg_1);
create bitmap index tq84_bitmap_or_ix_2 on tq84_bitmap_or(flg_2);
 
begin
   insert into tq84_bitmap_or
   select
      level,
      dbms_random.value(10000, 99999),
      case mod(level, 1000)
           when 123  then 'foo'
           when 456  then 'bar'
           when 789  then 'baz' end,
      case mod(level, 1234)
           when 222  then 'x'
           when 444  then 'y'   end,
      lpad('x', 2222, 'x')
   from
      dual connect by level <= 10000;
  
   commit;
   dbms_stats.gather_table_stats(user, 'tq84_bitmap_or');
end;
/
 
 
explain plan for
select
   id,
   val
from
   tq84_bitmap_or
where
   flg_1 in ('foo', 'bar', 'baz') or
   flg_2 in ('x', 'y');
  
 
 
select * from dbms_xplan.display(format => 'basic');
--
-- -------------------------------------------------------------------
-- | Id  | Operation                           | Name                |
-- -------------------------------------------------------------------
-- |   0 | SELECT STATEMENT                    |                     |
-- |   1 |  TABLE ACCESS BY INDEX ROWID BATCHED| TQ84_BITMAP_OR      |
-- |   2 |   BITMAP CONVERSION TO ROWIDS       |                     |
-- |   3 |    BITMAP OR                        |                     |
-- |   4 |     BITMAP INDEX SINGLE VALUE       | TQ84_BITMAP_OR_IX_1 |
-- |   5 |     BITMAP INDEX SINGLE VALUE       | TQ84_BITMAP_OR_IX_1 |
-- |   6 |     BITMAP INDEX SINGLE VALUE       | TQ84_BITMAP_OR_IX_1 |
-- |   7 |     BITMAP INDEX SINGLE VALUE       | TQ84_BITMAP_OR_IX_2 |
-- |   8 |     BITMAP INDEX SINGLE VALUE       | TQ84_BITMAP_OR_IX_2 |
-- -------------------------------------------------------------------
 
 
drop table tq84_bitmap_or;

See also

BITMAP INDEX RANGE SCAN
Plan operations

Index

Fatal error: Uncaught PDOException: SQLSTATE[HY000]: General error: 8 attempt to write a readonly database in /home/httpd/vhosts/renenyffenegger.ch/php/web-request-database.php:78 Stack trace: #0 /home/httpd/vhosts/renenyffenegger.ch/php/web-request-database.php(78): PDOStatement->execute(Array) #1 /home/httpd/vhosts/renenyffenegger.ch/php/web-request-database.php(30): insert_webrequest_('/notes/developm...', 1758199817, '216.73.216.150', 'Mozilla/5.0 App...', NULL) #2 /home/httpd/vhosts/renenyffenegger.ch/httpsdocs/notes/development/databases/Oracle/SQL/statement/execution/plan/operations/bitmap-index/single-value/index(209): insert_webrequest() #3 {main} thrown in /home/httpd/vhosts/renenyffenegger.ch/php/web-request-database.php on line 78