> For the complete documentation index, see [llms.txt](https://docs.pinot.apache.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.pinot.apache.org/build-with-pinot/indexing/range-index.md).

# Range Index

This page describes configuring the range index for Apache Pinot.

Range indexing allows you to get better performance for queries that involve filtering over a range.

## When to use

Use a range index when queries filter on a column with range predicates such as `>`, `<`, `>=`, `<=`, or `BETWEEN`. It is especially effective on metric columns with high cardinality, where an inverted index would be too large.

{% hint style="info" %}
A good rule of thumb is to use a range index when you want to apply range predicates on metric columns that have a very large number of unique values. Using an inverted index for such columns creates a very large index that is inefficient in terms of storage and performance.
{% endhint %}

## How it works

A range index is a variant of an [inverted index](/build-with-pinot/indexing/inverted-index.md). Instead of creating a mapping from individual values to document IDs, it creates a mapping from a range of values to document IDs. At query time Pinot uses the range index to quickly identify the set of documents whose column values fall within the requested range.

## Supported column types

Range index is supported on:

* Dictionary-enabled columns of any data type except MAP (INT, LONG, FLOAT, DOUBLE, STRING, BIG\_DECIMAL, BYTES, BOOLEAN, TIMESTAMP). The dictionary can be paired with either a dictionary-encoded forward index or a RAW forward index with a standalone dictionary.
* Raw-encoded columns without a dictionary for numeric types (INT, LONG, FLOAT, DOUBLE, BIG\_DECIMAL).

For [ingestion-aggregated](/build-with-pinot/ingestion/transformations-and-aggregations/ingestion-level-aggregations.md) no-dictionary metric columns, a version `2` range index is supported on committed segments. When an older segment lacks min/max metadata for a raw `INT` or `LONG` column, adding the index requires an extra scan of its forward index to recover that range.

{% hint style="info" %}
A range index can also be used on a dictionary-encoded time column using `STRING` type, because Pinot only supports datetime formats that are in lexicographical order.
{% endhint %}

## Configuration

The recommended way to enable a range index is through the `fieldConfigList` in the [table configuration](/reference/configuration-reference/table.md):

{% code title="Recommended: fieldConfigList" %}

```json
{
  "fieldConfigList": [
    {
      "name": "hits",
      "indexes": {
        "range": {}
      }
    }
  ]
}
```

{% endcode %}

You can also specify the range index version (default is `2`):

{% code title="With explicit version" %}

```json
{
  "fieldConfigList": [
    {
      "name": "hits",
      "indexes": {
        "range": {
          "version": 2
        }
      }
    }
  ]
}
```

{% endcode %}

If the column keeps a RAW forward index but also needs a dictionary for the range index, configure the standalone dictionary explicitly and use range index version `2`:

{% code title="RAW forward index with dictionary-backed range index" %}

```json
{
  "fieldConfigList": [
    {
      "name": "eventDate",
      "encodingType": "RAW",
      "indexes": {
        "dictionary": {},
        "range": {
          "version": 2
        }
      }
    }
  ]
}
```

{% endcode %}

Range index version `1` is rejected for the combination of RAW forward index plus dictionary, because version `1` can fall back to scans that compare raw forward values with dictionary-ID evaluators. Version `2` uses the BitSliced range index and is the required form for RAW + dictionary.

<details>

<summary>Older configuration</summary>

The older approach uses `rangeIndexColumns` in `tableIndexConfig`:

{% code title="Legacy: tableIndexConfig" %}

```json
{
  "tableIndexConfig": {
    "rangeIndexColumns": [
      "hits"
    ]
  }
}
```

{% endcode %}

</details>

## Query examples

```sql
SELECT COUNT(*)
FROM baseballStats
WHERE hits > 11
```

```sql
SELECT playerName, hits
FROM baseballStats
WHERE hits BETWEEN 50 AND 100
ORDER BY hits DESC
LIMIT 20
```

```sql
SELECT teamID, AVG(hits) AS avgHits
FROM baseballStats
WHERE hits >= 10 AND hits <= 200
GROUP BY teamID
ORDER BY avgHits DESC
```

## Limitations

* The range index does not support MAP columns.
* When the forward index is disabled for a column, the column must be single-valued and use range index version 2 for range queries to work.
* Numeric RAW columns can use a range index without a dictionary. Non-numeric RAW columns need a dictionary, and RAW + dictionary range indexes must use version 2.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.pinot.apache.org/build-with-pinot/indexing/range-index.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
