Hi,
For records of type Order as defined below, I want to be able to truncate the total sorted range of records scanned by passing a filter on the primary key but record layer doesn’t seem to allow that when an additional Or component is present in the query as it converts the filter to a disjunctive normal form.
message Order {
int64 order_id = 1;
int32 price = 2;
}
The following are the query passed and plan generated for the case when there is no Or component within the And component.
RecordQuery.newBuilder()
.setRecordType("Order")
.setFilter(Query.and(
Query.field("order_id").greaterThanOrEquals(101L),
Query.field("order_id").lessThanOrEquals(102L)))
.setSort(Key.Expressions.field("order_id"),false)
.build();
Query Plan: Scan([[101],>) | [Order] | order_id LESS_THAN_OR_EQUALS 102
The following are the query passed and plan generated for the case when there is an additional Or component within the And component.
RecordQuery query = RecordQuery.newBuilder()
.setRecordType("Order")
.setFilter(Query.and(
Query.field("order_id").greaterThanOrEquals(101L),
Query.field("order_id").lessThanOrEquals(102L),
Query.or(Query.field("price").equalsValue(2),
Query.field("price").equalsValue(2))))
.setSort(Key.Expressions.field("order_id"),true)
.build();
Query Plan: Scan(<,>) | [Order] | Or([And([order_id LESS_THAN_OR_EQUALS 102, order_id GREATER_THAN_OR_EQUALS 101, price EQUALS 2]), And([order_id LESS_THAN_OR_EQUALS 102, order_id GREATER_THAN_OR_EQUALS 101, price EQUALS 2])])
Note that in the first query only the greaterThanOrEquals filter on order_id is used to truncate the scan (when the order of filters is switched and lessThanOrEquals filter on order_id is specified before then the lessThanOrEquals filter is used).
Further, in the second query, none of the filters on order_id are used to truncate the scan range. This makes the query slow.
Any thoughts/suggestions on how I can counter this?