Skip to content

New Setting to enable successive time range queries over a large overall time range #111413

Description

@knudtty

Company or project name

ClickStack @ ClickHouse

Use case

Ability to short circuit non read_in_order top N queries and pseudo-streaming of aggregation functions.

Describe the solution you'd like

A setting(s) that allows specifying a time bucketing column and varying time buckets to execute multiple queries. Example usage would be time_range_identifier='Timestamp', time_range_buckets='1m,15m,1h,6h,6h,12h,24h'. In the case where the time range queried exceeds the sum total of the time range buckets, the final time bucket is used for further time bucket queries. For the example of settings I've given applied to a 4 day range query, the subqueries are issued in succession with time ranges of 1m, 15m, 1h, 6h, 6h, 12h, 24h, 24h, and 22h44m. For Top N queries with an ORDER BY and LIMIT, the query can be short circuited once the LIMIT is hit. For Aggregation queries that are grouping by the time_range_identifier, results can be streamed back to the client upon each successive query.

Describe alternatives you've considered

Application level logic (explained in the Additional context). However, each application that seeks these benefits must implement them on their own, and there is an opportunity for a db level feature so that each application can benefit.

Recursive CTEs almost get you there, but I don't believe you can short circuit them. Also, they're pretty ugly.

The read_in_order optimization is the only short circuit mechanism that I know of, but it isn't always feasible. Additionally, read_in_order isn't applicable to aggregation queries like I outlined.

Additional context

In ClickStack, we are constantly trying to optimize performant queries and user experience. Some time ago, we saw on large datasets that Top N and aggregation queries over large time ranges will often take several seconds, and the users were not satisfied with watching loading spinners for many seconds. We implemented some application level logic to issue successive queries over increasingly large time ranges.

For a top N query example, imagine we want to display 200 rows over a time range in descending order where the overall time range is 24 hours. First the application breaks up the time range into several "windows" over a 1 minute time range with a limit. The returned rows are evaluated. If the limit was met, no further queries are sent. If the limit was not met, a successive query is issued from the application over the next 15 minutes in the time range with an adjusted limit based on how many rows were returned from the first query. This pattern is repeated with increasingly large time ranges (1m -> 15m -> 1h -> 6h -> 6h -> 12h -> 24h), until either the limit is reached or the search over the entire time range has been executed.

For an aggregation query example, imagine we have a line chart displaying a sum aggregation of some Value column over a time range. Aggregated sum values are grouped by some time bucketing transformation (eg. toStartOfMinute(Timestamp)). The application issues a queries successively over the entire time range following the same bucket sizing (1m -> 15m -> 1h -> 6h -> 6h -> 12h -> 24h) and displays results as they arrive.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions