All Products
Search
Document Center

Hologres:Get started with Hologres indexes

Last Updated:Jun 21, 2026

This topic introduces key indexes in Hologres, such as the distribution key, event time column (segment key), and clustering key, to help you get started with indexes and improve query performance during Hologres development.

How Hologres works

Hologres is a distributed data warehouse that uses parallel and vector computing to deliver query responses in seconds. Because of this architecture, data distribution is critical for performance. This includes how data is balanced across distributed nodes, which is governed by the distribution key, and how data is ordered within the files on a single node, which is governed by the event time column (also known as segment key). Hologres uses a columnar storage format by default for online analytical processing (OLAP) scenarios, making the order of data within a file, which is governed by the clustering key, also essential. Mastering these three concepts is key to optimizing performance. Because these data layout properties are set when data is written and are costly to change, we recommend that you design your tables with these three attributes from the start. Attributes that do not directly affect data layout, such as bitmap indexes and dictionary encoding, can be adjusted later as needed.

Hologres uses a three-level metadata structure: Database > Schema > Table. To avoid cross-database queries, we recommend grouping logically related tables under the same schema. A database is a basic unit for metadata isolation, not resource isolation.

SQL optimization basics

Designing tables with an appropriate data distribution strategy enables SQL queries to quickly locate data. This reduces I/O, consumes fewer computing resources, and achieves higher query performance. A balanced data distribution also ensures concurrent resources are used efficiently, avoiding single-point bottlenecks. The following diagram illustrates how a SQL query retrieves data and how I/O is reduced.image

  • Partition pruning: When a SQL query targets a partitioned table, the query optimizer uses partition pruning to locate the relevant partitions. If the query's filter conditions do not include the partition key, the query must scan all partitions, which causes excessive I/O. As a general rule, partitioning by day is a good practice. Partition pruning is skipped for non-partitioned tables.

  • Shard pruning: Use the distribution key to quickly locate the data shard that contains the required data. This reduces resource consumption for a single query and supports higher throughput for concurrent queries. If a specific shard cannot be located, the distributed framework schedules all shards to participate in the computation. This increases the parallelism for a single query but uses more resources and lowers overall concurrency. Some operators that require centralized execution can also introduce extra shuffle overhead. As a best practice, choose columns with even data distribution, such as order IDs, user IDs, or event IDs, as the distribution key. If multiple tables that need to be joined share the same distribution key, related data is co-located on the same shard. This enables efficient local join operations.

  • Segment key pruning: Use the segment key (event time column) to quickly locate the specific data file within a node, which avoids accessing unnecessary files. If data cannot be filtered at this level, all files must be scanned.

  • Clustering key pruning: Use the clustering key to quickly locate data segments within a single file. This improves the efficiency of range queries and column sorting.

SQL optimization in practice

This section uses TPC-H queries to demonstrate how to set Hologres indexes for better query performance. For more information about TPC-H, see Test plan overview.

TPC-H SQL reference

TPC-H Q1 query

The TPC-H Q1 query performs aggregations and filtering on specific columns of the lineitem table. It includes the following condition:

l_shipdate <=: This is a filter condition. To support efficient range filtering and quickly retrieve the required data, you must define an appropriate index.

--TPC-H Q1
SELECT
        l_returnflag,
        l_linestatus,
        SUM(l_quantity) AS sum_qty,
        SUM(l_extendedprice) AS sum_base_price,
        SUM(l_extendedprice * (1 - l_discount)) AS sum_disc_price,
        SUM(l_extendedprice * (1 - l_discount) * (1 + l_tax)) AS sum_charge,
        AVG(l_quantity) AS avg_qty,
        AVG(l_extendedprice) AS avg_price,
        AVG(l_discount) AS avg_disc,
        COUNT(*) AS count_order
FROM
        lineitem
WHERE
        l_shipdate <= DATE '1998-12-01' - INTERVAL '120' DAY
GROUP BY
        l_returnflag,
        l_linestatus
ORDER BY
        l_returnflag,
        l_linestatus;

TPC-H Q4 query

The TPC-H Q4 query primarily joins the lineitem and orders tables. It includes the following conditions:

  • o_orderdate >= DATE '1996-07-01': This is a filter condition. To support efficient range filtering and quickly retrieve the required data, you must define an appropriate index.

  • l_orderkey = o_orderkey: This is a join condition between the two tables. For best performance, use the same index on both tables to enable a local join, which reduces data shuffling during the operation.

    --TPC-H Q4 Query
    SELECT
            o_orderpriority,
            COUNT(*) AS order_count
    FROM
            orders
    WHERE
            o_orderdate >= DATE '1996-07-01'
            AND o_orderdate < DATE '1996-07-01' + INTERVAL '3' MONTH
            AND EXISTS (
                    SELECT
                            *
                    FROM
                            lineitem
                    WHERE
                            l_orderkey = o_orderkey
                            AND l_commitdate < l_receiptdate
            )
    GROUP BY
            o_orderpriority
    ORDER BY
            o_orderpriority;

Table creation recommendations

The Q1 and Q4 queries involve the lineitem and orders tables.

hologres_dataset_tpch_100g.lineitem

Both the Q1 and Q4 queries involve the lineitem table, but they use different columns and conditions.

  • For the Q1 query: The query primarily uses l_shipdate for range filtering. The clustering key accelerates range scans by leveraging the sorted order of data within files. Therefore, set l_shipdate as the clustering key. The segment key (event time column) maintains order between files. For a monotonically increasing or decreasing date column, setting it as the segment key enables effective segment key pruning. Therefore, you can also set l_shipdate as the segment key.

  • For the Q4 query: The query joins the lineitem table with the orders table on the l_orderkey and o_orderkey columns. The distribution key specifies the data distribution strategy. The system places data with the same key value on the same shard. If two tables are in the same table group and are joined on their distribution key columns, the system automatically distributes matching records to the same shard during data writes. When these tables are joined, the system performs a local join on each node without shuffling data across the network. This avoids runtime data shuffling and redistribution, significantly improving execution efficiency. Therefore, set l_orderkey as the distribution key.

  • The final table structure for lineitem is as follows:

    BEGIN;
    CREATE TABLE hologres_dataset_tpch_100g.lineitem
    (
        l_ORDERKEY      BIGINT      NOT NULL,
        L_PARTKEY       INT         NOT NULL,
        L_SUPPKEY       INT         NOT NULL,
        L_LINENUMBER    INT         NOT NULL,
        L_QUANTITY      DECIMAL(15,2) NOT NULL,
        L_EXTENDEDPRICE DECIMAL(15,2) NOT NULL,
        L_DISCOUNT      DECIMAL(15,2) NOT NULL,
        L_TAX           DECIMAL(15,2) NOT NULL,
        L_RETURNFLAG    TEXT        NOT NULL,
        L_LINESTATUS    TEXT        NOT NULL,
        L_SHIPDATE      TIMESTAMPTZ NOT NULL,
        L_COMMITDATE    TIMESTAMPTZ NOT NULL,
        L_RECEIPTDATE   TIMESTAMPTZ NOT NULL,
        L_SHIPINSTRUCT  TEXT        NOT NULL,
        L_SHIPMODE      TEXT        NOT NULL,
        L_COMMENT       TEXT        NOT NULL,
        PRIMARY KEY (L_ORDERKEY,L_LINENUMBER)
    )
    WITH (
        distribution_key = 'L_ORDERKEY',--Enables local join.
        clustering_key = 'L_SHIPDATE',--Accelerates range filtering.
        event_time_column = 'L_SHIPDATE'--Accelerates segment key pruning.
      );
    COMMIT;

hologres_dataset_tpch_100g.orders

In this example, the orders table is used in the Q4 query.

  • Set the o_orderkey column of the orders table as the distribution key to leverage local join capabilities and improve join query efficiency.

  • The o_orderdate column is primarily used for date filtering. Set it as the segment key to accelerate segment key pruning.

  • The final table structure for orders is as follows:

    BEGIN;
    CREATE TABLE hologres_dataset_tpch_100g.orders
    (
        O_ORDERKEY      BIGINT      NOT NULL PRIMARY KEY,
        O_CUSTKEY       INT         NOT NULL,
        O_ORDERSTATUS   TEXT        NOT NULL,
        O_TOTALPRICE    DECIMAL(15,2) NOT NULL,
        O_ORDERDATE     timestamptz NOT NULL,
        O_ORDERPRIORITY TEXT        NOT NULL,
        O_CLERK         TEXT        NOT NULL,
        O_SHIPPRIORITY  INT         NOT NULL,
        O_COMMENT       TEXT        NOT NULL
    )
    WITH (
        distribution_key = 'O_ORDERKEY',--Enables local join.
        event_time_column = 'O_ORDERDATE'--Accelerates segment key pruning.
      );
    COMMIT;

Import sample data

You can quickly import 100 GB of TPC-H data into your Hologres instance using the Import public datasets with a few clicks feature in HoloWeb. In HoloWeb, select Data Solutions from the top navigation bar, and then click Import public datasets with a few clicks in the left-side navigation pane. On the configuration page, select an Instance Name (for example, holo_test) and a Database. Then, select tpch_100g from the Public Dataset Name list. The system automatically generates a non-editable SQL script at the bottom of the page. This script includes statements to create the hologres_foreign_dataset_tpch_100g and hologres_dataset_tpch_100g schemas, and to sequentially import data into foreign tables such as customer, lineitem, nation, orders, part, partsupp, region, and supplier.

Performance test results

This section compares query performance before and after setting the recommended table properties (indexes).

  • Test environment

    • Instance specification: 32-core

    • Network type: VPC

    • Execute each query twice using a PSQL client and record the latency of the second execution.

  • Conclusion

    • For filtered queries on a single table, setting the filter column as the clustering key effectively accelerates the query.

    • For multi-table join queries, setting the join columns as the distribution key significantly improves join efficiency.

    Query

    Latency with indexes

    Latency without indexes

    Q1

    48.293 ms

    59.483 ms

    Q4

    822.389 ms

    3027.957 ms

References

More information

Technical principles

Deep dive into the core technical principles of Hologres (architecture, storage engine, and compute engine): Core Technology of Alibaba Cloud's Cloud-native Real-time Data Warehouse.

Service activation

Data import

Data query

O&M and monitoring

Use cases and best practices

Practices and use cases: Best practices and classic customer use cases for typical industry scenarios.