min_max index
min_max index is a local index that speeds up scanning queries with a highly selective filter by skipping fragments. Unlike global secondary indexes, it acts as a read filter for the base table and reduces the amount of data that actually needs to be read.
For each indexed data fragment, the min_max index stores the minimum and maximum value of one column. During query execution, YDB evaluates the predicate on these two values. If the evaluation results show that the predicate will filter out all tuples of the fragment, the fragment is skipped.
Examples
Creation syntax: CREATE TABLE, ALTER TABLE ADD INDEX.
Creating a columnar table with a min_max index:
CREATE TABLE events (
id Uint64,
created_at Timestamp,
level Int32,
resource_id Utf8,
PRIMARY KEY (id),
INDEX idx_created_at LOCAL USING min_max
ON (created_at),
INDEX idx_level LOCAL USING min_max
ON (level)
)
WITH (
STORE = COLUMN
);
Adding a min_max index to an existing columnar table:
ALTER TABLE events
ADD INDEX idx_resource_id LOCAL USING min_max
ON (resource_id);
Queries with range predicates can use the index to skip non-matching fragments:
SELECT id, resource_id
FROM events
WHERE created_at BETWEEN Timestamp("2024-01-01T00:00:00.000000Z")
AND Timestamp("2024-01-02T00:00:00.000000Z");
When to use
The min_max index is useful when the values of the indexed column change little between rows that are adjacent in the primary key order: for example, timestamps, monotonically increasing identifiers, or other values correlated with the primary key.
The min_max index can also be useful when the filter predicate selects a very small fraction of the data (on the order of one row per million). For example, when querying a service log table and keeping only records with the ERROR level: if the service writes one error per 1,000,000 records, the min_max index will likely significantly reduce the read volume.
Features and limitations
- The index is always local (
LOCAL); there is no global variant. - Queries do not use the
VIEW <index>syntax (unlike, for example, full-text indexes). - The filter is applied during reads only to data fragments for which the minimum and maximum values of the indexed column have already been computed and stored with the table data at write time or merge. For other fragments, no skip by this index is performed.
Limitations
- Supported only for columnar tables.
ON (...)must specify exactly one column.COVER (...)and additional data columns are not supported.- Specific parameters of
WITH (...)are not supported. ALTER INDEXis not supported for the min_max index.- Columns of types
JsonandJsonDocumentare not supported.