Aggregation with window so slowly

Q = from(bucket:“timeseries”)
|> range(start: 2021-01-01T00:00:01.000Z, stop: 2021-07-18T21:11:52.999Z)
QVmax = Q
|> aggregateWindow(every: 20s480ms, fn:max )
QVmin = Q
|> aggregateWindow(every: 20s480ms, fn:min )
QTmin = Q
|> aggregateWindow(every: 20s480ms, fn:first )
QTmax = Q
|> aggregateWindow(every: 20s480ms, fn:last )
union(tables: [QVmax,QVmin,QTmin,QTmax])

my server with 256G memeory and 64 core cpu. this bucket has 2m points.I want to know if there is any good way to optimize it.

from(bucket:“timeseries”)
|> range(start: 2021-01-01T00:00:01.000Z, stop: 2021-07-18T21:11:52.999Z)

The second question is that it takes 4 seconds to run the above query, is this normal?

Hello @Yuchun_Wang,
Why do you need to union the tables?
Perhaps you can skip this?

Q = from(bucket:“timeseries”)
|> range(start: 2021-01-01T00:00:01.000Z, stop: 2021-07-18T21:11:52.999Z)
QVmax = Q
|> aggregateWindow(every: 20s480ms, fn:max )
|> yield(name: "1")
QVmin = Q
|> aggregateWindow(every: 20s480ms, fn:min )
|> yield(name: "2")
QTmin = Q
|> aggregateWindow(every: 20s480ms, fn:first )
|> yield(name: "3")
QTmax = Q
|> aggregateWindow(every: 20s480ms, fn:last )
|> yield(name: "4")

Also the from |> range |> filter |> aggwindow is a pusdown pattern its possible that this is more efficient but i haven’t tested it:

 from(bucket:“timeseries”)
|> range(start: 2021-01-01T00:00:01.000Z, stop: 2021-07-18T21:11:52.999Z)
|> aggregateWindow(every: 20s480ms, fn:max )
|> yield(name: "1")

 from(bucket:“timeseries”)
|> range(start: 2021-01-01T00:00:01.000Z, stop: 2021-07-18T21:11:52.999Z)
|> aggregateWindow(every: 20s480ms, fn:min )
|> yield(name: "2")

 from(bucket:“timeseries”)
|> range(start: 2021-01-01T00:00:01.000Z, stop: 2021-07-18T21:11:52.999Z)
|> aggregateWindow(every: 20s480ms, fn:first )
|> yield(name: "3")

 from(bucket:“timeseries”)
|> range(start: 2021-01-01T00:00:01.000Z, stop: 2021-07-18T21:11:52.999Z)
|> aggregateWindow(every: 20s480ms, fn:last )
|> yield(name: "4")