All Products
Search
Document Center

PolarDB:Distributed columnar index

Last Updated:Oct 14, 2026

PolarDB for PostgreSQL Distributed Editionintegrates the DuckDB analytical engine into its columnstore index (IMCI) feature, which improves analytical query performance by more than 60 times. Combined with the transparent sharding mechanism of the distributed architecture, queries can be pushed down to multiple data nodes (DNs) for parallel processing, so analytical performance scales linearly with the number of nodes. For big data volumes at the TB or PB scale, the combination of the distributed architecture and IMCI improves overall analytical performance by nearly 100 times compared with the row store, which meets the requirements of HTAP (hybrid transactional and analytical processing) scenarios.

Architecture

image

The distributed architecture with IMCI includes the following core components:

  • Coordinator node (CN): Processes requests, generates distributed execution plans, pushes query SQL down to each data node, and finally aggregates the results from all DNs before returning them to the client.

  • Data node (DN): Stores data in both row-store and column-store (IMCI) formats. Row-store data is asynchronously written to the column store through the logical replication mechanism, which ensures that analytical acceleration is compatible with real-time data writes.

The following example describes the overall workflow of a typical analytical aggregate query:

  1. The CN generates a distributed plan and dispatches SQL: A business SQL request is sent to the CN. The CN generates a distributed execution plan based on global metadata and determines how to split the query SQL and push it down to each data node.

  2. DNs run parallel queries on IMCI column-store data: The CN pushes the query down to each target DN. Each DN runs an efficient parallel query and performs preliminary aggregation on its local IMCI column-store data, and then returns the intermediate results to the CN.

  3. The CN performs secondary aggregation and returns the final result: The CN collects the query results from all DNs, performs final aggregation and sorting as required, and returns the aggregated result to the user or application.

Scenarios

This feature applies to multi-tenant database scenarios, especially when tenant data must be rolled up and aggregated globally with high efficiency, which significantly improves analytical performance. It applies to the following two sharding scenarios:

Horizontal sharding (sharding by tenant_id)

Assume that a business table orders exists and uses tenant_id as the sharding key.

  • Single-tenant aggregation: Calculates the total and average amounts of the local orders of a specific tenant.

    SELECT SUM(amount) AS total_amount, AVG(amount) AS avg_amount
    FROM orders
    WHERE tenant_id = 1001;
  • Global tenant statistics: Calculates the total and average order amounts of all tenants, grouped by tenant.

    SELECT tenant_id, SUM(amount) AS total_amount, AVG(amount) AS avg_amount
    FROM orders
    GROUP BY tenant_id;

Vertical sharding (sharding by schema)

Assume that the data of each tenant is stored in a separate schema and that the table is named orders in every schema.

  • Single-schema aggregation: Aggregates the total and average order amounts of a specific schema.

    SELECT SUM(amount) AS total_amount, AVG(amount) AS avg_amount
    FROM tenant_a.orders;
  • Global tenant statistics: Aggregates the total and average order amounts of all tenants by using UNION ALL.

    SELECT 'tenant_a' AS tenant, SUM(amount) AS total_amount, AVG(amount) AS avg_amount FROM tenant_a.orders
    UNION ALL
    SELECT 'tenant_b' AS tenant, SUM(amount) AS total_amount, AVG(amount) AS avg_amount FROM tenant_b.orders;

Prerequisites

Configure the distributed columnstore index

Step 1: Enable the distributed IMCI feature

You can modify the parameters in the PolarDB console or in a database session:

Parameter

Description

polar_cluster_enable_imci

Specifies whether to enable the distributed columnstore index.

  • on: enables the feature.

  • off (default): disables the feature.

polar_csi.enable_anyall_to_in

Specifies whether IN expressions in WHERE conditions can use the distributed columnstore index.

  • on: enables the feature.

  • off (default): disables the feature.

pg_hint_plan.polar_enable_distributed_hint

Specifies whether to enable the distributed hint feature.

  • on: enables the feature.

  • off (default): disables the feature.

SET polar_cluster_enable_imci = on;
SET polar_csi.enable_anyall_to_in = on;
SET pg_hint_plan.polar_enable_distributed_hint = on;

Step 2: Create replication slots for row-to-column synchronization

Use an account with high privileges to run the following command on the primary CN to create replication slots for row-to-column synchronization on all nodes:

SELECT run_command_on_all_nodes($$ SELECT polar_csi_start_sync() $$);
Note

This operation is idempotent and can be run multiple times without side effects.

Step 3: Create and shard tenant tables

Horizontal sharding

Create a distributed table that uses tenant_id as the sharding key:

Note

If you use tenant_id as the sharding key, it must be the primary key or part of the primary key.

-- Create the initial business table with tenant_id as part of the primary key
CREATE TABLE orders (
  order_id   bigint,
  tenant_id  int NOT NULL,
  amount     numeric(20,2),
  status     text,
  create_time timestamp,
  PRIMARY KEY (tenant_id, order_id)
);

-- Convert the table to a distributed sharded table
SELECT create_distributed_table('orders', 'tenant_id');

Vertical sharding

The data of each tenant is stored in a separate schema:

-- Create the tenant schema
CREATE SCHEMA tenant1;

-- Enable distributed management for the schema
SELECT polar_cluster_schema_distribute('tenant1');

-- Create the business table
SET search_path TO tenant1;

CREATE TABLE orders (
  order_id   bigint,
  tenant_id  int NOT NULL,
  amount     numeric(20,2),
  status     text,
  create_time timestamp,
  PRIMARY KEY (tenant_id, order_id)
);

Step 4: Create a columnstore index

Create a CSI columnstore index on the table:

-- Create a columnstore index on all columns
CREATE INDEX csi_orders ON orders USING CSI;

-- Create a columnstore index on specific columns only (for example, when queries involve only tenant_id and amount)
CREATE INDEX csi_orders_part ON orders1 USING CSI(tenant_id, order_id, amount);

-- Create a columnstore index without locking the table (recommended)
CREATE INDEX CONCURRENTLY csi_orders ON orders USING CSI;
Note

(Recommended) Create a CSI on all columns to prevent column-store queries from becoming ineffective due to missing columns.

Step 5: Run queries by using the columnstore index

Two parameters control whether a column-store query is run:

Parameter

Description

polar_csi.enable_query

Specifies whether query statements can use a columnstore index.

  • on: enables the feature.

  • off (default): disables the feature.

polar_csi.cost_threshold

The cost threshold of a query. If the query cost is lower than the specified threshold, the row-store engine is used. Otherwise, the column-store engine is used.

  • Value range: 0 to 1000000000

  • Default value: 50000

(Recommended) Use a hint to force a specific query to use the columnstore index:

/*+SET (polar_csi.enable_query on) SET(polar_csi.cost_threshold 0)*/
SELECT tenant_id, SUM(amount) AS total_amount, AVG(amount) AS avg_amount
FROM orders
GROUP BY tenant_id;

You can also set the parameters globally or per account. To set the parameters globally, modify them in the console. To set the parameters per account, run the following statements on the primary CN:

-- Prioritize the columnstore index for the test user
ALTER ROLE test SET polar_csi.enable_query = ON;
ALTER ROLE test SET polar_csi.cost_threshold = 0;

Step 6: Check whether a query uses the columnstore index

You can use EXPLAIN for analysis. If CSI Executor appears in the execution plan, the query uses the columnstore index:

/*+SET (polar_csi.enable_query on) SET(polar_csi.cost_threshold 0)*/
EXPLAIN (COSTS OFF) SELECT tenant_id, SUM(amount) AS total_amount, AVG(amount) AS avg_amount
FROM orders
GROUP BY tenant_id;

Example output snippet (the presence of CSI Executor indicates that the column-store query is used):

                       QUERY PLAN
---------------------------------------------------------
 Custom Scan (PolarCluster Adaptive)
   Task Count: 32
   Tasks Shown: One of 32
   ->  Task
         Node: host=127.0.0.1 port=45719 dbname=postgres
         ->  CSI Executor:
             ┌───────────────────────────┐
             │       HASH_GROUP_BY       │
             │    ────────────────────   │
             │        Aggregates:        │
             │          sum(#1)          │
             │          avg(#2)          │
             └─────────────┬─────────────┘
             ┌─────────────┴─────────────┐
             │         SEQ_SCAN          │
             │    ────────────────────   │
             │    Table: orders_102008   │
             │   Type: Sequential Scan   │
             └───────────────────────────┘

Performance

The following performance tests demonstrate the horizontal scaling capability and performance of the distributed architecture with IMCI in different data processing scenarios. In the test environment, each DN has 16 cores and 64 GB of memory.

  • Sysbench OLTP (online transaction processing) test: This test is mainly used to evaluate database performance under transactional operations such as inserts, updates, and deletes with high concurrency. As the number of data nodes (DNs) increases, the write capacity of the system scales almost linearly to meet the requirements of growing service traffic.

  • TPC-H OLAP (online analytical processing) test: This test focuses on the performance of large-scale data aggregation and complex query analysis. IMCI significantly improves the analytical capability of a single node, and the distributed architecture further pushes queries down to multiple DNs for parallel processing. As a result, overall query performance scales linearly with the number of nodes, which is suitable for analyzing and gaining insights from massive data volumes.

TPC-H performance test

The query latency is tested with 1, 2, 4, 8, and 12 DNs by using a 1 TB TPC-H dataset.

image

The test results show that:

  • The query latency of the distributed column store can be improved by more than 100 times compared with the distributed row store, and it scales linearly.

  • Compared with a column-store query on a single node, the distributed architecture with IMCI also achieves linear multiplicative gains as the number of DNs increases. A 12-DN configuration improves performance by several tens of times compared with a single node.

Sysbench OLTP_INSERT test

The write QPS of the distributed cluster is measured with 1, 2, 4, 8, and 12 DNs.image

The test results show that:

  • Write QPS scales linearly with the number of DNs: As the number of DNs increases from 1 to 12, the write QPS grows almost linearly and reaches a maximum of 1.6 million QPS with 12 DNs.

  • The distributed architecture horizontally scales row-to-column synchronization: The parallel multi-DN architecture improves write performance and significantly enhances logical replication replay, which makes the data synchronization latency from the row store to the column store (IMCI) near real time.