Skip to content

Learn to use multiple projections [+ PK] for filtering granules #55525

@nickitat

Description

@nickitat

Imagine we have a table like this one:

create table t(a UInt32, b UInt32, ts DateTime64) engine=MergeTree order by tuple();

And the user wants to write queries like this:

select * from t where (a = 2 or b = 333333) and ts >= 5 and ts <= 50;

It seems reasonable to add two projections: at as (select * order by a, ts), bt as (select * order by b, ts) and use both for filtering granules.

Currently it doesn't work and require rewrite like this:

select * from t where (a = 2 and ts >= 5 and ts <= 50) union all select * from t where (b = 333333 and a != 2 and ts >= 5 and ts <= 50);

While it seems that for this case at least we could rewrite the filter predicate into DNF like this:

where (a = 2 and ts >= 5 and ts <= 50) or (b = 333333 and ts >= 5 and ts <= 50)

analyse each conjunction separately and choose at for the lhs and bt for the rhs. Then merge two sets of selected granules and read only them.

all sql for this example: https://fiddle.clickhouse.com/9b123f48-2843-4067-ad1f-89af8839ceb7

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions