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
Imagine we have a table like this one:
And the user wants to write queries like this:
It seems reasonable to add two projections:
atas(select * order by a, ts),btas(select * order by b, ts)and use both for filtering granules.Currently it doesn't work and require rewrite like this:
While it seems that for this case at least we could rewrite the filter predicate into DNF like this:
analyse each conjunction separately and choose
atfor the lhs andbtfor 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