All Products
Search
Document Center

MaxCompute:Bitmap index (Beta)

Last Updated:Mar 26, 2026

Bitmap indexes improve point query and range query performance for columns with high-frequency duplicate values, filtering out more than 60% of data in range filtering scenarios. Use bitmap indexes on low-cardinality columns to accelerate AND, OR, and multidimensional queries.

MaxCompute supports four index types: hash-clustered index, range-clustered index, Bloom filter index, and bitmap index. Range-clustered indexes are suitable for range filtering using the leftmost matching principle. Bloom filter indexes are suitable for point queries. Bitmap indexes are not subject to the leftmost matching principle—each query operates independently and can be combined with other index types.

When to use bitmap indexes

Bitmap indexes work best for:

  • Low-cardinality columns with a limited number of distinct values, such as gender or city

  • Logical operations (AND, OR)—bitmap indexes perform efficient bitwise operations, making them well-suited for multidimensional queries

When not to use bitmap indexes

Avoid creating bitmap indexes for:

  • High-cardinality columns with many distinct values, such as ID card numbers or phone numbers. When too many distinct values exist or filtering is ineffective, index storage overhead increases and read performance degrades.

  • Frequently updated columns. Frequent updates to indexed columns increase storage overhead and degrade read performance.

Supported column types and operators

Bitmap indexes can only be created on non-nested columns of these types: STRING, CHAR, VARCHAR, TINYINT, SMALLINT, INT, BIGINT, and DOUBLE.

Once created, bitmap indexes accelerate queries that use these operators:

Operator Example
= WHERE job = 'clerk'
< WHERE empno < 7500
<= WHERE empno <= 7500
> WHERE empno > 7500
>= WHERE empno >= 7500
IN WHERE job IN ('clerk', 'analyst')
BETWEEN WHERE empno BETWEEN 7300 AND 7800
IS NULL WHERE mgr IS NULL

Billing

  • Storage: Bitmap indexes consume additional storage space, calculated by actual index size. This storage is consolidated with your project data and billed at the standard storage rate.

  • Computing: Index creation triggers additional compute jobs.

    • Subscription: Jobs use the subscription resources of the project.

    • Pay-as-you-go: Cost = Unit price of pay-as-you-go SQL jobs × Complexity 1 × Input data amount of index-related jobs

Prerequisites

Before creating a bitmap index, enable schema evolution on the project:

setproject odps.schema.evolution.enable=true;

Usage notes

  • Create a bitmap index for one column at a time. To index multiple columns on the same table, run the creation statement once per column.

  • Data inserted after index creation is automatically covered by the bitmap index.

  • To apply a bitmap index to existing data, rebuild the index after creation.

Sample data

The examples in this topic use two tables: emp (non-partitioned) and sale_detail (partitioned).

Non-partitioned table

  1. Create the emp table.

    CREATE TABLE IF NOT EXISTS emp(
      empno BIGINT,
      ename STRING,
      job STRING,
      mgr BIGINT,
      sex STRING
    );
  2. Insert sample data.

    INSERT INTO emp(empno,ename,job,mgr,sex) VALUES
    (7369,'smith','clerk',7902,'Male'),
    (7499,'allen','salesman',7698,'Female'),
    (7521,'ward','salesman',7698,'Male'),
    (7654,'martin','salesman',7698,'Male'),
    (7698,'blake','manager',7839,'Male'),
    (7782,'clark','manager',7839,'Male'),
    (7788,'scott','analyst',7566,'Male'),
    (7839,'king','president',NULL,'Male'),
    (7844,'turner','salesman',7698,'Female'),
    (7876,'adams','clerk',7788,'Female'),
    (7900,'james','clerk',7698,'Male'),
    (7902,'ford','analyst',7566,'Male'),
    (7934,'miller','clerk',7782,'Female');

Partitioned table

  1. Create the sale_detail table.

    CREATE TABLE IF NOT EXISTS sale_detail(
     shop_name     STRING,
     customer_id   STRING,
     total_price   DOUBLE)
    PARTITIONED BY (sale_date STRING, region STRING);
  2. Add partitions.

    ALTER TABLE sale_detail ADD PARTITION (sale_date='2023', region='china') PARTITION (sale_date='2024', region='shanghai');

Create a bitmap index

Syntax

CREATE BITMAP INDEX <index_name> ON TABLE <table_name> FOR COLUMNS(<col_name>) [COMMENT 'indexcomment'];

Parameters

Parameter Required Description
index_name Yes Name of the index
table_name Yes Name of the table
col_name Yes Name of the column to index

Examples

Create the empno_index bitmap index on the empno column of the emp table:

CREATE BITMAP INDEX empno_index
ON TABLE emp
FOR COLUMNS(empno)
COMMENT 'idxcomment';

Create the job_index bitmap index on the job column of the emp table:

CREATE BITMAP INDEX job_index
ON TABLE emp
FOR COLUMNS(job)
COMMENT 'idxcomment';

Create the shop_name_index bitmap index on the shop_name column of the sale_detail table:

CREATE BITMAP INDEX shop_name_index
ON TABLE sale_detail
FOR COLUMNS(shop_name)
COMMENT 'indexcomment';

Rebuild a bitmap index

Rebuild a bitmap index to apply it to existing data that was present before the index was created.

Syntax

For non-partitioned tables:

ALTER TABLE <table_name> REBUILD BITMAP INDEX;

For partitioned tables:

ALTER TABLE <table_name> PARTITION
(<partition_name1=value1>[, partition_name2=value2, ...]) REBUILD BITMAP INDEX;
For partitioned tables, rebuild one partition at a time.

Parameters

Parameter Required Description
table_name Yes Name of the table
partition_name Yes (partitioned tables) Name of the partition key
value Yes (partitioned tables) Partition key value

Examples

Rebuild a bitmap index for the non-partitioned emp table:

ALTER TABLE emp REBUILD BITMAP INDEX;

Rebuild a bitmap index for a specific partition of the sale_detail table:

ALTER TABLE sale_detail PARTITION (sale_date='2023', region='china') REBUILD BITMAP INDEX;

List bitmap indexes

Syntax

SHOW INDEXES ON <table_name>;

Example

-- List indexes on the emp table
SHOW INDEXES ON emp;

The result is returned as JSON:

{"Indexes": [{
            "id": "00c84b0e9e6e4097bdfe3a01b91848ac",
            "indexColumns": [{"name": "job"}],
            "name": "job_index",
            "properties": {"comment": "jobidx"},
            "type": "BITMAP"},
           {
            "id": "18a9755c7a8a4182a6b51165e786aa62",
            "indexColumns": [{"name": "empno"}],
            "name": "empno_index",
            "properties": {"comment": "idxcomment"},
            "type": "BITMAP"}]}

Query data with bitmap indexes

The following examples show point and range queries on the emp table with bitmap indexes applied.

Point query — filter by the job column:

SELECT * FROM emp WHERE job = 'clerk';

Result:

+------------+-------+-----+------------+------------+-----+
| empno      | ename | job | mgr        | hiredate   | sex |
+------------+-------+-----+------------+------------+-----+
| 7369       | smith | clerk | 7902       | NULL       | Male |
| 7876       | adams | clerk | 7788       | NULL       | Female |
| 7900       | james | clerk | 7698       | NULL       | Male |
| 7934       | miller | clerk | 7782       | NULL       | Female |
+------------+-------+-----+------------+------------+-----+

Range query — filter by a range of empno values:

SELECT * FROM emp WHERE empno BETWEEN 7300 AND 7800;

Result:

+------------+------------+------------+------------+------------+
| empno      | ename      | job        | mgr        | sex        |
+------------+------------+------------+------------+------------+
| 7369       | smith      | clerk      | 7902       | Male       |
| 7499       | allen      | salesman   | 7698       | Female     |
| 7521       | ward       | salesman   | 7698       | Male       |
| 7654       | martin     | salesman   | 7698       | Male       |
| 7698       | blake      | manager    | 7839       | Male       |
| 7782       | clark      | manager    | 7839       | Male       |
| 7788       | scott      | analyst    | 7566       | Male       |
+------------+------------+------------+------------+------------+

Verify that bitmap indexes are filtering data

After running a query, check the filtering effect in the operational logs:

  1. In the console, click the LogView URL in the operational logs to open the LogView page.

    image

  2. On the Json Summary tab, search for the bitmap keyword. The results show the number of rows filtered by bitmap indexes and the additional time consumed for creating bitmap indexes. I/O operation time is not included in this measurement.

    image

Drop a bitmap index

Syntax

DROP INDEX [IF EXISTS] <index_name> ON TABLE <table_name>;

Parameters

Parameter Required Description
index_name Yes Name of the index to drop
table_name Yes Name of the table

Example

DROP INDEX IF EXISTS job_index ON TABLE emp;