> 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

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).

{% 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 dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

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

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
