Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Charge level regression line #4187

Closed

Conversation

swiffer
Copy link
Contributor

@swiffer swiffer commented Sep 7, 2024

this is an enhancement for the charge level dashboard and is built on top of #4186

by enabling the regression transformation feature toggle in grafana it allows showing a regression line for the charge level

grafik

details on the feature and feature toggles in general

grafana/grafana#78457
https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/feature-toggles/

Copy link

netlify bot commented Sep 7, 2024

Deploy Preview for teslamate ready!

Name Link
🔨 Latest commit 22da7b2
🔍 Latest deploy log https://app.netlify.com/sites/teslamate/deploys/66dc149d82e35b0008450b3f
😎 Deploy Preview https://deploy-preview-4187--teslamate.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@swiffer swiffer marked this pull request as draft September 8, 2024 15:38
@swiffer
Copy link
Contributor Author

swiffer commented Sep 8, 2024

@JakobLichterfeld - still experimenting a little bit with some added lines to add value to the charge level dashboard.

could you please guide on what is favored? regression via plugin or showing moving percentiles within the graph?

I'll update the PR afterwards based on your preference (mine would be the percentiles, not the regression line)

I figured out pure PostgreSQL based solutions - see outcome and concepts used in the links below:

grafik

Making use of TimescaleDB Hyperfunctions would have made the query way easier to write and read but I guess switching our DB is not an option currently.

before updating the PR - could someone run the query below (6 months+ history) and note the query time please?

with sample_set as (
	select date, battery_level from positions p where p.car_id = 2 and p.battery_level is not null
	-- union all
	-- select date, battery_level, usable_battery_level from charges c inner join charging_processes cp on c.charging_process_id = cp.id and cp.car_id = 2
), date_series as (
	select generate_series('2024-03-08T15:19:38.536Z', '2024-09-08T14:19:38.536Z', (10800000 / 1 || ' milliseconds')::INTERVAL) as series_id
), date_series_bucketing as (
	select series_id, lead(series_id) over (order by series_id asc) as next_series_id from date_series
), bucketing as (
	select 
		series_id, avg(battery_level) as battery_level
	from date_series_bucketing
	left join sample_set on
		sample_set.date >= date_series_bucketing.series_id
		and sample_set.date < date_series_bucketing.next_series_id
	group by series_id
), locf_intermediate as (
	select series_id, battery_level, count(battery_level) over (order by series_id) as i from bucketing
), bucketing_gapfill as (
	select series_id, max(battery_level) over (partition by i) as battery_level from locf_intermediate
), trick as (
	select series_id, battery_level, array_agg(battery_level) over (rows between 125 preceding and 125 following) as arr from bucketing_gapfill
)
select series_id,
    case when battery_level is null then null else(SELECT percentile_cont(0.075) within group (ORDER BY s)
    FROM unnest(arr) trick(s)) end as p0075,
    case when battery_level is null then null else(SELECT percentile_cont(0.5) within group (ORDER BY s)
    FROM unnest(arr) trick(s)) end as p050,
    case when battery_level is null then null else(SELECT percentile_cont(0.925) within group (ORDER BY s)
    FROM unnest(arr) trick(s)) end as p0925
from trick;

@JakobLichterfeld JakobLichterfeld added the area:dashboard Related to a Grafana dashboard label Sep 9, 2024
@JakobLichterfeld
Copy link
Collaborator

Thanks for your suggestion and effort!

could you please guide on what is favored? regression via plugin or showing moving percentiles within the graph?

Personally, I don't think we need a forecast for the charge level (which would be a benefit of using regression). I think moving percentiles are well suited as we want more transparency about the distribution of the charge states and detailed insights into the charging behavior.

Making use of TimescaleDB Hyperfunctions would have made the query way easier to write and read but I guess switching our DB is not an option currently.

As TimescaleDB Hyperfunctions is an extenstion to PosgreSQL I could imagine doing the migration effort if we do need the additional performance. I personally do not yet have extensive knowledge of TimescaleDB Hyperfunctions.

before updating the PR - could someone run the query below (6 months+ history) and note the query time please?

I changed it to car_id = 1 but didn't get any output, can you double check the syntax?

@swiffer
Copy link
Contributor Author

swiffer commented Sep 12, 2024

Hi @JakobLichterfeld - the query should output 1472 rows even if you are selecting a non existing car right now.

could you run the query again and append an EXPLAIN ANALYZE in front of the query?

@JakobLichterfeld
Copy link
Collaborator

JakobLichterfeld commented Sep 12, 2024

Hi @JakobLichterfeld - the query should output 1472 rows even if you are selecting a non existing car right now.

could you run the query again and append an EXPLAIN ANALYZE in front of the query?

Sorry for not providing the non-existent error message in first place :-)
image

@swiffer
Copy link
Contributor Author

swiffer commented Sep 12, 2024

Super Strange... what version of postgres are you using? @DrMichael could you maybe run the query?

@JakobLichterfeld
Copy link
Collaborator

Super Strange... what version of postgres are you using?

PostgreSQL16

@swiffer
Copy link
Contributor Author

swiffer commented Sep 13, 2024

Please terminate the Query with ; 🫣

@JakobLichterfeld
Copy link
Collaborator

JakobLichterfeld commented Sep 13, 2024

Please terminate the Query with ; 🫣

😀 That's what I was looking for with

can you double check the syntax?

I changed your comment with the query above

with EXPLAIN ANALYZE

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Subquery Scan on trick  (cost=112.45..219.45 rows=200 width=32) (actual time=34.540..346.705 rows=1472 loops=1)
   ->  WindowAgg  (cost=112.45..120.45 rows=200 width=72) (actual time=34.533..344.951 rows=1472 loops=1)
         ->  Subquery Scan on bucketing_gapfill  (cost=112.45..117.95 rows=200 width=40) (actual time=34.022..37.424 rows=1472 loops=1)
               ->  WindowAgg  (cost=112.45..115.95 rows=200 width=48) (actual time=34.019..36.203 rows=1472 loops=1)
                     ->  Sort  (cost=112.45..112.95 rows=200 width=48) (actual time=30.719..31.332 rows=1472 loops=1)
                           Sort Key: locf_intermediate.i
                           Sort Method: quicksort  Memory: 90kB
                           ->  Subquery Scan on locf_intermediate  (cost=55.28..104.80 rows=200 width=48) (actual time=5.984..28.824 rows=1472 loops=1)
                                 ->  WindowAgg  (cost=55.28..104.80 rows=200 width=48) (actual time=5.980..27.491 rows=1472 loops=1)
                                       ->  GroupAggregate  (cost=55.28..101.80 rows=200 width=40) (actual time=5.946..20.159 rows=1472 loops=1)
                                             Group Key: (generate_series('2024-03-08 15:19:38.536+00'::timestamp with time zone, '2024-09-08 14:19:38.536+00'::timestamp with time zone, ('10800000 milliseconds'::cstring)::interval))
                                             ->  Nested Loop Left Join  (cost=55.28..94.30 rows=1000 width=10) (actual time=5.905..15.620 rows=1472 loops=1)
                                                   Join Filter: ((p.date >= (generate_series('2024-03-08 15:19:38.536+00'::timestamp with time zone, '2024-09-08 14:19:38.536+00'::timestamp with time zone, ('10800000 milliseconds'::cstring)::interval))) AND (p.date < (lead((generate_series('2024-03-08 15:19:38.536+00'::timestamp with time zone, '2024-09-08 14:19:38.536+00'::timestamp with time zone, ('10800000 milliseconds'::cstring)::interval))) OVER (?))))
                                                   ->  WindowAgg  (cost=54.85..72.35 rows=1000 width=16) (actual time=2.687..9.706 rows=1472 loops=1)
                                                         ->  Sort  (cost=54.85..57.35 rows=1000 width=8) (actual time=2.659..3.492 rows=1472 loops=1)
                                                               Sort Key: (generate_series('2024-03-08 15:19:38.536+00'::timestamp with time zone, '2024-09-08 14:19:38.536+00'::timestamp with time zone, ('10800000 milliseconds'::cstring)::interval))
                                                               Sort Method: quicksort  Memory: 56kB
                                                               ->  ProjectSet  (cost=0.00..5.02 rows=1000 width=8) (actual time=0.363..1.611 rows=1472 loops=1)
                                                                     ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual time=0.003..0.005 rows=1 loops=1)
                                                   ->  Materialize  (cost=0.43..4.46 rows=1 width=10) (actual time=0.003..0.003 rows=0 loops=1472)
                                                         ->  Index Scan using positions_car_id_index on positions p  (cost=0.43..4.45 rows=1 width=10) (actual time=3.193..3.193 rows=0 loops=1)
                                                               Index Cond: (car_id = 2)
                                                               Filter: (battery_level IS NOT NULL)
   SubPlan 1
     ->  Aggregate  (cost=0.16..0.17 rows=1 width=8) (never executed)
           ->  Function Scan on unnest trick_1  (cost=0.00..0.10 rows=10 width=32) (never executed)
   SubPlan 2
     ->  Aggregate  (cost=0.16..0.17 rows=1 width=8) (never executed)
           ->  Function Scan on unnest trick_2  (cost=0.00..0.10 rows=10 width=32) (never executed)
   SubPlan 3
     ->  Aggregate  (cost=0.16..0.17 rows=1 width=8) (never executed)
           ->  Function Scan on unnest trick_3  (cost=0.00..0.10 rows=10 width=32) (never executed)
 Planning Time: 36.497 ms
 Execution Time: 349.111 ms
(34 rows)

~
(END)

and without EXPLAIN ANALYZE

         series_id          | p0075 | p050 | p0925
----------------------------+-------+------+-------
 2024-03-08 15:19:38.536+00 |       |      |
 2024-03-08 18:19:38.536+00 |       |      |
 2024-03-08 21:19:38.536+00 |       |      |
 2024-03-09 00:19:38.536+00 |       |      |
 2024-03-09 03:19:38.536+00 |       |      |
 2024-03-09 06:19:38.536+00 |       |      |
 2024-03-09 09:19:38.536+00 |       |      |
(...)
 2024-09-01 21:19:38.536+00 |       |      |
 2024-09-02 00:19:38.536+00 |       |      |
 2024-09-02 03:19:38.536+00 |       |      |
 2024-09-02 06:19:38.536+00 |       |      |
 2024-09-02 09:19:38.536+00 |       |      |
 2024-09-02 12:19:38.536+00 |       |      |
 2024-09-02 15:19:38.536+00 |       |      |
 2024-09-02 18:19:38.536+00 |       |      |
 2024-09-02 21:19:38.536+00 |       |      |
 2024-09-03 00:19:38.536+00 |       |      |
 2024-09-03 03:19:38.536+00 |       |      |
 2024-09-03 06:19:38.536+00 |       |      |
 2024-09-03 09:19:38.536+00 |       |      |
 2024-09-03 12:19:38.536+00 |       |      |
 2024-09-03 15:19:38.536+00 |       |      |
 2024-09-03 18:19:38.536+00 |       |      |
 2024-09-03 21:19:38.536+00 |       |      |
 2024-09-04 00:19:38.536+00 |       |      |
 2024-09-04 03:19:38.536+00 |       |      |
 2024-09-04 06:19:38.536+00 |       |      |
 2024-09-04 09:19:38.536+00 |       |      |
 2024-09-04 12:19:38.536+00 |       |      |
 2024-09-04 15:19:38.536+00 |       |      |
 2024-09-04 18:19:38.536+00 |       |      |
 2024-09-04 21:19:38.536+00 |       |      |
 2024-09-05 00:19:38.536+00 |       |      |
 2024-09-05 03:19:38.536+00 |       |      |
 2024-09-05 06:19:38.536+00 |       |      |
 2024-09-05 09:19:38.536+00 |       |      |
 2024-09-05 12:19:38.536+00 |       |      |
 2024-09-05 15:19:38.536+00 |       |      |
 2024-09-05 18:19:38.536+00 |       |      |
 2024-09-05 21:19:38.536+00 |       |      |
 2024-09-06 00:19:38.536+00 |       |      |
 2024-09-06 03:19:38.536+00 |       |      |
 2024-09-06 06:19:38.536+00 |       |      |
 2024-09-06 09:19:38.536+00 |       |      |
 2024-09-06 12:19:38.536+00 |       |      |
 2024-09-06 15:19:38.536+00 |       |      |
 2024-09-06 18:19:38.536+00 |       |      |
 2024-09-06 21:19:38.536+00 |       |      |
 2024-09-07 00:19:38.536+00 |       |      |
 2024-09-07 03:19:38.536+00 |       |      |
 2024-09-07 06:19:38.536+00 |       |      |
 2024-09-07 09:19:38.536+00 |       |      |
 2024-09-07 12:19:38.536+00 |       |      |
 2024-09-07 15:19:38.536+00 |       |      |
 2024-09-07 18:19:38.536+00 |       |      |
 2024-09-07 21:19:38.536+00 |       |      |
 2024-09-08 00:19:38.536+00 |       |      |
 2024-09-08 03:19:38.536+00 |       |      |
 2024-09-08 06:19:38.536+00 |       |      |
 2024-09-08 09:19:38.536+00 |       |      |
 2024-09-08 12:19:38.536+00 |       |      |
(1472 rows)

(END)

@swiffer
Copy link
Contributor Author

swiffer commented Sep 13, 2024

Can you change car_id to 1 again to get results?

@JakobLichterfeld
Copy link
Collaborator

Can you change car_id to 1 again to get results?

For sure, aborted one after 9 minutes right now, as I do not want the Rpi to hang while the car is charging, will redo later today.

@swiffer
Copy link
Contributor Author

swiffer commented Sep 13, 2024

sure - takes less than 1 second on my instance with 2 cars, 25k km in total. let's see what explain analyze returns, hopefully i can find a way to improve speed for lower spec instances.

@coreGreenberet
Copy link
Contributor

coreGreenberet commented Sep 13, 2024

I've executed your query a few times and it took about 21 to 24 seconds every time (with car_id=1)

QUERY PLAN"
Subquery Scan on trick  (cost=64177453.11..64177562.11 rows=200 width=32) (actual time=18586.049..23503.173 rows=1472 loops=1)"
  ->  WindowAgg  (cost=64177453.11..64177461.11 rows=200 width=72) (actual time=18584.154..18989.049 rows=1472 loops=1)"
        ->  Subquery Scan on bucketing_gapfill  (cost=64177453.11..64177458.61 rows=200 width=40) (actual time=12318.653..12336.000 rows=1472 loops=1)"
              ->  WindowAgg  (cost=64177453.11..64177456.61 rows=200 width=48) (actual time=12318.646..12333.758 rows=1472 loops=1)"
                    ->  Sort  (cost=64177453.11..64177453.61 rows=200 width=48) (actual time=12318.575..12319.905 rows=1472 loops=1)"
                          Sort Key: locf_intermediate.i"
                          Sort Method: quicksort  Memory: 147kB"
                          ->  Subquery Scan on locf_intermediate  (cost=65.29..64177445.46 rows=200 width=48) (actual time=77.422..12314.795 rows=1472 loops=1)"
                                ->  WindowAgg  (cost=65.29..64177443.46 rows=200 width=48) (actual time=77.415..12312.604 rows=1472 loops=1)"
                                      ->  GroupAggregate  (cost=65.29..64177438.46 rows=200 width=40) (actual time=43.932..12301.568 rows=1472 loops=1)"
                                            Group Key: (generate_series('2024-03-08 16:19:38.536+01'::timestamp with time zone, '2024-09-08 16:19:38.536+02'::timestamp with time zone, ('10800000 milliseconds'::cstring)::interval))"
                                            ->  Nested Loop Left Join  (cost=65.29..55745769.85 rows=1686333222 width=10) (actual time=1.989..11271.056 rows=3156786 loops=1)"
                                                  ->  WindowAgg  (cost=64.85..82.35 rows=1000 width=16) (actual time=1.512..14.495 rows=1472 loops=1)"
                                                        ->  Sort  (cost=64.85..67.35 rows=1000 width=8) (actual time=1.472..3.043 rows=1472 loops=1)"
                                                              Sort Key: (generate_series('2024-03-08 16:19:38.536+01'::timestamp with time zone, '2024-09-08 16:19:38.536+02'::timestamp with time zone, ('10800000 milliseconds'::cstring)::interval))"
                                                              Sort Method: quicksort  Memory: 118kB"
                                                              ->  ProjectSet  (cost=0.00..5.02 rows=1000 width=8) (actual time=0.062..0.742 rows=1472 loops=1)"
                                                                    ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual time=0.006..0.008 rows=1 loops=1)"
                                                  ->  Index Scan using positions_date_index on positions p  (cost=0.43..38882.35 rows=1686333 width=10) (actual time=0.084..6.726 rows=2144 loops=1472)"
                                                        Index Cond: ((date >= (generate_series('2024-03-08 16:19:38.536+01'::timestamp with time zone, '2024-09-08 16:19:38.536+02'::timestamp with time zone, ('10800000 milliseconds'::cstring)::interval))) AND (date < (lead((generate_series('2024-03-08 16:19:38.536+01'::timestamp with time zone, '2024-09-08 16:19:38.536+02'::timestamp with time zone, ('10800000 milliseconds'::cstring)::interval))) OVER (?))))"
                                                        Filter: ((battery_level IS NOT NULL) AND (car_id = 1))"
                                                        Rows Removed by Filter: 0"
  SubPlan 1"
    ->  Aggregate  (cost=0.16..0.17 rows=1 width=8) (actual time=1.027..1.028 rows=1 loops=1472)"
          ->  Function Scan on unnest trick_1  (cost=0.00..0.10 rows=10 width=32) (actual time=0.151..0.221 rows=240 loops=1472)"
  SubPlan 2"
    ->  Aggregate  (cost=0.16..0.17 rows=1 width=8) (actual time=1.003..1.003 rows=1 loops=1472)"
          ->  Function Scan on unnest trick_2  (cost=0.00..0.10 rows=10 width=32) (actual time=0.146..0.213 rows=240 loops=1472)"
  SubPlan 3"
    ->  Aggregate  (cost=0.16..0.17 rows=1 width=8) (actual time=1.007..1.007 rows=1 loops=1472)"
          ->  Function Scan on unnest trick_3  (cost=0.00..0.10 rows=10 width=32) (actual time=0.150..0.218 rows=240 loops=1472)"
Planning Time: 2.441 ms"
JIT:"
  Functions: 57"
  Options: Inlining true, Optimization true, Expressions true, Deforming true"
  Timing: Generation 79.818 ms, Inlining 304.931 ms, Optimization 3765.506 ms, Emission 2188.292 ms, Total 6338.547 ms"
Execution Time: 23585.525 ms"

@JakobLichterfeld
Copy link
Collaborator

JakobLichterfeld commented Sep 13, 2024

let's see what explain analyze returns, hopefully i can find a way to improve speed for lower spec instances.

The Rpi reboots during the query (not a memory issue but CPu gets to hot), so no output. Will try with shorter timeframe

@JakobLichterfeld
Copy link
Collaborator

Will try with shorter timeframe

Tried with

EXPLAIN ANALYZE with sample_set as (
        select date, battery_level from positions p where p.car_id = 1 and p.battery_level is not null
        -- union all
        -- select date, battery_level, usable_battery_level from charges c inner join charging_processes cp on c.charging_process_id = cp.id and cp.car_id = 1
), date_series as (
        select generate_series('2024-08-01T00:00:01.000Z', '2024-09-13T23:59:59.000Z', (10800000 / 1 || ' milliseconds')::INTERVAL) as series_id
), date_series_bucketing as (
        select series_id, lead(series_id) over (order by series_id asc) as next_series_id from date_series
), bucketing as (
        select
                series_id, avg(battery_level) as battery_level
        from date_series_bucketing
        left join sample_set on
                sample_set.date >= date_series_bucketing.series_id
                and sample_set.date < date_series_bucketing.next_series_id
        group by series_id
), locf_intermediate as (
        select series_id, battery_level, count(battery_level) over (order by series_id) as i from bucketing
), bucketing_gapfill as (
        select series_id, max(battery_level) over (partition by i) as battery_level from locf_intermediate
), trick as (
        select series_id, battery_level, array_agg(battery_level) over (rows between 125 preceding and 125 following) as arr from bucketing_gapfill
)
select series_id,
    case when battery_level is null then null else(SELECT percentile_cont(0.075) within group (ORDER BY s)
    FROM unnest(arr) trick(s)) end as p0075,
    case when battery_level is null then null else(SELECT percentile_cont(0.5) within group (ORDER BY s)
    FROM unnest(arr) trick(s)) end as p050,
    case when battery_level is null then null else(SELECT percentile_cont(0.925) within group (ORDER BY s)
    FROM unnest(arr) trick(s)) end as p0925
from trick;

And aborted after 1h11m33s

@swiffer
Copy link
Contributor Author

swiffer commented Sep 13, 2024

@JakobLichterfeld - can you try the following two queries? (sorry but it's hard to improve runtimes without knowing timings and what is slowing it down in your system. query execution is 300ms here...

select count(*) from positions p where p.car_id = 1 and date between '2024-09-01T00:00:01.000Z' and '2024-09-13T23:59:59.000Z' and p.battery_level is not null;
EXPLAIN ANALYZE with sample_set as (
        select date, battery_level from positions p where p.car_id = 1 and date between '2024-09-01T00:00:01.000Z' and '2024-09-13T23:59:59.000Z' and p.battery_level is not null
        -- union all
        -- select date, battery_level, usable_battery_level from charges c inner join charging_processes cp on c.charging_process_id = cp.id and cp.car_id = 1
), date_series as (
        select generate_series('2024-09-01T00:00:01.000Z', '2024-09-13T23:59:59.000Z', (10800000 / 1 || ' milliseconds')::INTERVAL) as series_id
), date_series_bucketing as (
        select series_id, lead(series_id) over (order by series_id asc) as next_series_id from date_series
), bucketing as (
        select
                series_id, avg(battery_level) as battery_level
        from date_series_bucketing
        left join sample_set on
                sample_set.date >= date_series_bucketing.series_id
                and sample_set.date < date_series_bucketing.next_series_id
        group by series_id
), locf_intermediate as (
        select series_id, battery_level, count(battery_level) over (order by series_id) as i from bucketing
), bucketing_gapfill as (
        select series_id, max(battery_level) over (partition by i) as battery_level from locf_intermediate
), trick as (
        select series_id, battery_level, array_agg(battery_level) over (rows between 125 preceding and 125 following) as arr from bucketing_gapfill
)
select series_id,
    case when battery_level is null then null else(SELECT percentile_cont(0.075) within group (ORDER BY s)
    FROM unnest(arr) trick(s)) end as p0075,
    case when battery_level is null then null else(SELECT percentile_cont(0.5) within group (ORDER BY s)
    FROM unnest(arr) trick(s)) end as p050,
    case when battery_level is null then null else(SELECT percentile_cont(0.925) within group (ORDER BY s)
    FROM unnest(arr) trick(s)) end as p0925
from trick;

@JakobLichterfeld
Copy link
Collaborator

JakobLichterfeld commented Sep 13, 2024

Yeah sorry, I was thinking about splitting the query to find the root cause as well.

select count(*) from positions p where p.car_id = 1 and date between '2024-09-01T00:00:01.000Z' and '2024-09-13T23:59:59.000Z' and p.battery_level is not null

with EXPLAIN ANALYZE and ; at the end

                                                                                               QUERY PLAN              
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Aggregate  (cost=127766.34..127766.35 rows=1 width=8) (actual time=47428.881..49319.385 rows=1 loops=1)
   ->  Gather  (cost=1000.00..127766.33 rows=1 width=0) (actual time=47230.977..49274.355 rows=108817 loops=1)
         Workers Planned: 2
         Workers Launched: 2
         ->  Parallel Seq Scan on positions p  (cost=0.00..126766.23 rows=1 width=0) (actual time=42907.622..42979.595 rows=36272 loops=3)
               Filter: ((battery_level IS NOT NULL) AND (date >= '2024-09-01 00:00:01'::timestamp without time zone) AND (date <= '2024-09-13 23:59:59'::timestamp without time zone) AND (car_id = 1))
               Rows Removed by Filter: 2077526
 Planning Time: 11.502 ms
 JIT:
   Functions: 11
   Options: Inlining false, Optimization false, Expressions true, Deforming true
   Timing: Generation 29.442 ms, Inlining 0.000 ms, Optimization 480.674 ms, Emission 2836.354 ms, Total 3346.471 ms
 Execution Time: 49342.482 ms
(13 rows)

And

                                                                                                 QUERY PLAN


-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
 Subquery Scan on trick  (cost=127874.33..127981.33 rows=200 width=32) (actual time=64148.879..64302.192 rows=104 loops
=1)
   ->  WindowAgg  (cost=127874.33..127882.33 rows=200 width=72) (actual time=64137.677..64139.951 rows=104 loops=1)
         ->  Subquery Scan on bucketing_gapfill  (cost=127874.33..127879.83 rows=200 width=40) (actual time=63213.098..
63214.196 rows=104 loops=1)
               ->  WindowAgg  (cost=127874.33..127877.83 rows=200 width=48) (actual time=63213.077..63214.097 rows=104
loops=1)
                     ->  Sort  (cost=127874.33..127874.83 rows=200 width=48) (actual time=63212.904..63213.531 rows=104
 loops=1)
                           Sort Key: locf_intermediate.i
                           Sort Method: quicksort  Memory: 21kB
                           ->  Subquery Scan on locf_intermediate  (cost=1054.85..127866.69 rows=200 width=48) (actual time=35064.298..63212.815 rows=104 loops=1)
                                 ->  WindowAgg  (cost=1054.85..127866.69 rows=200 width=48) (actual time=35064.266..63212.419 rows=104 loops=1)
                                       ->  GroupAggregate  (cost=1054.85..127863.69 rows=200 width=40) (actual time=34725.644..63209.998 rows=104 loops=1)
                                             Group Key: (generate_series('2024-09-01 00:00:01+00'::timestamp with time zone, '2024-09-13 23:59:59+00'::timestamp with time zone, ('10800000 milliseconds'::cstring)::interval))
                                             ->  Nested Loop Left Join  (cost=1054.85..127856.19 rows=1000 width=10) (actual time=33650.833..63134.761 rows=108895 loops=1)
                                                   Join Filter: ((p.date >= (generate_series('2024-09-01 00:00:01+00'::timestamp with time zone, '2024-09-13 23:59:59+00'::timestamp with time zone, ('10800000 milliseconds'::cstring)::interval))) AND (p.date < (lead((generate_series('2024-09-01 00:00:01+00'::timestamp with time zone, '2024-09-13 23:59:59+00'::timestamp with time zone, ('10800000 milliseconds'::cstring)::interval))) OVER (?))))
                                                   Rows Removed by Join Filter: 11208151
                                                   ->  WindowAgg  (cost=54.85..72.35 rows=1000 width=16) (actual time=0.458..2.327 rows=104 loops=1)
                                                         ->  Sort  (cost=54.85..57.35 rows=1000 width=8) (actual time=0.360..0.661 rows=104 loops=1)
                                                               Sort Key: (generate_series('2024-09-01 00:00:01+00'::timestamp with time zone, '2024-09-13 23:59:59+00'::timestamp with time zone, ('10800000 milliseconds'::cstring)::interval))
                                                               Sort Method: quicksort  Memory: 18kB
                                                               ->  ProjectSet  (cost=0.00..5.02 rows=1000 width=8) (actual time=0.166..0.263 rows=104 loops=1)
                                                                     ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual time=0.024..0.028 rows=1 loops=1)
                                                   ->  Materialize  (cost=1000.00..127766.34 rows=1 width=10) (actual time=323.460..423.510 rows=108817 loops=104)
                                                         ->  Gather  (cost=1000.00..127766.33 rows=1 width=10) (actual time=33638.189..33901.109 rows=108817 loops=1)
                                                               Workers Planned: 2
                                                               Workers Launched: 2
                                                               ->  Parallel Seq Scan on positions p  (cost=0.00..126766.23 rows=1 width=10) (actual time=31140.078..31208.287 rows=36272 loops=3)
                                                                     Filter: ((battery_level IS NOT NULL) AND (date >= '2024-09-01 00:00:01'::timestamp without time zone) AND (date <= '2024-09-13 23:59:59'::timestamp without time zone) AND (car_id = 1))
                                                                     Rows Removed by Filter: 2077526
   SubPlan 1
     ->  Aggregate  (cost=0.16..0.17 rows=1 width=8) (actual time=0.575..0.575 rows=1 loops=104)
           ->  Function Scan on unnest trick_1  (cost=0.00..0.10 rows=10 width=32) (actual time=0.153..0.205 rows=104 loops=104)
   SubPlan 2
     ->  Aggregate  (cost=0.16..0.17 rows=1 width=8) (actual time=0.487..0.487 rows=1 loops=104)
           ->  Function Scan on unnest trick_2  (cost=0.00..0.10 rows=10 width=32) (actual time=0.073..0.125 rows=104 loops=104)
   SubPlan 3
     ->  Aggregate  (cost=0.16..0.17 rows=1 width=8) (actual time=0.478..0.479 rows=1 loops=104)
           ->  Function Scan on unnest trick_3  (cost=0.00..0.10 rows=10 width=32) (actual time=0.072..0.122 rows=104 loops=104)
 Planning Time: 15.421 ms
 JIT:
   Functions: 65
   Options: Inlining false, Optimization false, Expressions true, Deforming true
   Timing: Generation 47.192 ms, Inlining 0.000 ms, Optimization 157.808 ms, Emission 1451.909 ms, Total 1656.909 ms
 Execution Time: 64347.231 ms
(42 rows)

Ready to test more on the weekend

@swiffer
Copy link
Contributor Author

swiffer commented Sep 14, 2024

@JakobLichterfeld - there is an index in positions over date that should have been used for the first query - i wonder why it's not in your case...

grafik

could you run:

SELECT indexname AS index_name,
       tablename AS table_name
FROM pg_indexes
WHERE schemaname = 'public' and tablename = 'positions';

if the result shows an index named positions_date_index -> please run reindex index positions_date_index; afterwards.

@JakobLichterfeld
Copy link
Collaborator

JakobLichterfeld commented Sep 14, 2024

there is an index in positions over date that should have been used for the first query - i wonder why it's not in your case...

I think you may have hit on something there. We had a user who reported that the position table was not restored correctly from the backup, I could not find the issue/pr at the moment.

I do not have the positions_date_index

teslamate=# SELECT indexname AS index_name,
       tablename AS table_name
FROM pg_indexes
WHERE schemaname = 'public' and tablename = 'positions';
       index_name       | table_name
------------------------+------------
 positions_pkey         | positions
 positions_car_id_index | positions
(2 rows)

@swiffer
Copy link
Contributor Author

swiffer commented Sep 14, 2024

I'll prepare an overview of all indexes and a sql script to add all missing indexes later today. If others are affected we could add it to the docs section.

I restored from a backup last week (testing pg17) - worked without any issue here.

Let's see how the query performs afterwards, tried some other indexes, seeing enough potential to speed it and get this feature over the line!

I do have more time tomorrow, may ping you with some queries if ok for you.

@sdwalker
Copy link
Contributor

I'll plug https://github.com/jheredianet/Teslamate-CustomGrafanaDashboards/raw/main/dashboards/DatabaseDashboadInfo.json for details about the database

@JakobLichterfeld
Copy link
Collaborator

JakobLichterfeld commented Sep 15, 2024

Nice, thanks for pointing this out.

Screenshot_2024-09-15-06-43-24-55_40deb401b9ffe8e1df2f1cc5ba480b12.jpg

Screenshot_2024-09-15-06-43-36-58_40deb401b9ffe8e1df2f1cc5ba480b12.jpg

@swiffer
Copy link
Contributor Author

swiffer commented Sep 15, 2024

@JakobLichterfeld - looks like you are missing 8 indexes when comparing to my instance:

could you execute the sql below and afterwards run the two select statements mentioned here again?

#4187 (comment)

@coreGreenberet / @sdwalker - can you confirm a total of 36 indexes within your environments of teslamate via select count(*) from pg_indexes where schemaname = 'public';

corrective sql

CREATE UNIQUE INDEX IF NOT EXISTS addresses_osm_id_osm_type_index ON public.addresses USING btree (osm_id, osm_type);
CREATE UNIQUE INDEX IF NOT EXISTS addresses_pkey ON public.addresses USING btree (id);
CREATE UNIQUE INDEX IF NOT EXISTS car_settings_pkey ON public.car_settings USING btree (id);
CREATE UNIQUE INDEX IF NOT EXISTS cars_eid_index ON public.cars USING btree (eid);
CREATE UNIQUE INDEX IF NOT EXISTS cars_pkey ON public.cars USING btree (id);
CREATE UNIQUE INDEX IF NOT EXISTS cars_settings_id_index ON public.cars USING btree (settings_id);
CREATE UNIQUE INDEX IF NOT EXISTS cars_vid_index ON public.cars USING btree (vid);
CREATE UNIQUE INDEX IF NOT EXISTS cars_vin_index ON public.cars USING btree (vin);
CREATE INDEX IF NOT EXISTS charges_charging_process_id_index ON public.charges USING btree (charging_process_id);
CREATE INDEX IF NOT EXISTS charges_date_index ON public.charges USING btree (date);
CREATE UNIQUE INDEX IF NOT EXISTS charges_pkey ON public.charges USING btree (id);
CREATE INDEX IF NOT EXISTS charging_processes_address_id_index ON public.charging_processes USING btree (address_id);
CREATE INDEX IF NOT EXISTS charging_processes_car_id_index ON public.charging_processes USING btree (car_id);
CREATE UNIQUE INDEX IF NOT EXISTS charging_processes_pkey ON public.charging_processes USING btree (id);
CREATE INDEX IF NOT EXISTS charging_processes_position_id_index ON public.charging_processes USING btree (position_id);
CREATE INDEX IF NOT EXISTS drives_end_geofence_id_index ON public.drives USING btree (end_geofence_id);
CREATE INDEX IF NOT EXISTS drives_end_position_id_index ON public.drives USING btree (end_position_id);
CREATE INDEX IF NOT EXISTS drives_start_geofence_id_index ON public.drives USING btree (start_geofence_id);
CREATE INDEX IF NOT EXISTS drives_start_position_id_index ON public.drives USING btree (start_position_id);
CREATE INDEX IF NOT EXISTS trips_car_id_index ON public.drives USING btree (car_id);
CREATE INDEX IF NOT EXISTS trips_end_address_id_index ON public.drives USING btree (end_address_id);
CREATE UNIQUE INDEX IF NOT EXISTS trips_pkey ON public.drives USING btree (id);
CREATE INDEX IF NOT EXISTS trips_start_address_id_index ON public.drives USING btree (start_address_id);
CREATE UNIQUE INDEX IF NOT EXISTS geofences_pkey ON public.geofences USING btree (id);
CREATE INDEX IF NOT EXISTS positions_car_id_index ON public.positions USING btree (car_id);
CREATE INDEX IF NOT EXISTS positions_date_index ON public.positions USING btree (date);
CREATE INDEX IF NOT EXISTS positions_drive_id_date_index ON public.positions USING btree (drive_id, date);
CREATE UNIQUE INDEX IF NOT EXISTS positions_pkey ON public.positions USING btree (id);
CREATE UNIQUE INDEX IF NOT EXISTS schema_migrations_pkey ON public.schema_migrations USING btree (version);
CREATE UNIQUE INDEX IF NOT EXISTS settings_pkey ON public.settings USING btree (id);
CREATE UNIQUE INDEX IF NOT EXISTS "states_car_id__end_date_IS_NULL_index" ON public.states USING btree (car_id, ((end_date IS NULL))) WHERE (end_date IS NULL);
CREATE INDEX IF NOT EXISTS states_car_id_index ON public.states USING btree (car_id);
CREATE UNIQUE INDEX IF NOT EXISTS states_pkey ON public.states USING btree (id);
CREATE UNIQUE INDEX IF NOT EXISTS tokens_pkey ON public.tokens USING btree (id);
CREATE INDEX IF NOT EXISTS updates_car_id_index ON public.updates USING btree (car_id);
CREATE UNIQUE INDEX IF NOT EXISTS updates_pkey ON public.updates USING btree (id);

@JakobLichterfeld
Copy link
Collaborator

looks like you are missing 8 indexes when comparing to my instance:

Yeah, with a quick look into the migrations, I could not find one for positions_date_index for example.

Creating the indexes right now and will store a backup without the indexes for potential future testing.

@JakobLichterfeld
Copy link
Collaborator

JakobLichterfeld commented Sep 15, 2024

run the two select statements mentioned here again?

teslamate=# select count(*) from positions p where p.car_id = 1 and date between '2024-09-01T00:00:01.000Z' and '2024-09-13T23:59:59.000Z' and p.battery_level is not null;
 count
--------
 108817
(1 row)

and

                                                                                           QUERY PLAN                                                                                                                                                                                                                                                                                           
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Subquery Scan on trick  (cost=129128.92..129235.92 rows=200 width=32) (actual time=1295.137..1444.189 rows=104 loops=1)
   ->  WindowAgg  (cost=129128.92..129136.92 rows=200 width=72) (actual time=1293.132..1294.773 rows=104 loops=1)
         ->  Subquery Scan on bucketing_gapfill  (cost=129128.92..129134.42 rows=200 width=40) (actual time=753.184..753.685 rows=104 loops=1)
               ->  WindowAgg  (cost=129128.92..129132.42 rows=200 width=48) (actual time=753.163..753.590 rows=104 loops=1)
                     ->  Sort  (cost=129128.92..129129.42 rows=200 width=48) (actual time=753.020..753.078 rows=104 loops=1)
                           Sort Key: locf_intermediate.i
                           Sort Method: quicksort  Memory: 21kB
                           ->  Subquery Scan on locf_intermediate  (cost=55.28..129121.28 rows=200 width=48) (actual time=5.183..752.722 rows=104 loops=1)
                                 ->  WindowAgg  (cost=55.28..129121.28 rows=200 width=48) (actual time=5.164..752.541 rows=104 loops=1)
                                       ->  GroupAggregate  (cost=55.28..129118.28 rows=200 width=40) (actual time=5.030..751.688 rows=104 loops=1)
                                             Group Key: (generate_series('2024-09-01 00:00:01+00'::timestamp with time zone, '2024-09-13 23:59:59+00'::timestamp with time zone, ('10800000 milliseconds'::cstring)::interval))
                                             ->  Nested Loop Left Join  (cost=55.28..123350.78 rows=1153000 width=10) (actual time=4.805..680.663 rows=108895 loops=1)
                                                   ->  WindowAgg  (cost=54.85..72.35 rows=1000 width=16) (actual time=4.543..5.374 rows=104 loops=1)
                                                         ->  Sort  (cost=54.85..57.35 rows=1000 width=8) (actual time=4.457..4.569 rows=104 loops=1)
                                                               Sort Key: (generate_series('2024-09-01 00:00:01+00'::timestamp with time zone, '2024-09-13 23:59:59+00'::timestamp with time zone, ('10800000 milliseconds'::cstring)::interval))
                                                               Sort Method: quicksort  Memory: 18kB
                                                               ->  ProjectSet  (cost=0.00..5.02 rows=1000 width=8) (actual time=4.259..4.350 rows=104 loops=1)
                                                                     ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual time=0.027..0.028 rows=1 loops=1)
                                                   ->  Index Scan using positions_date_index on positions p  (cost=0.43..111.75 rows=1153 width=10) (actual time=0.110..5.777 rows=1046 loops=104)
                                                         Index Cond: ((date >= (generate_series('2024-09-01 00:00:01+00'::timestamp with time zone, '2024-09-13 23:59:59+00'::timestamp with time zone, ('10800000 milliseconds'::cstring)::interval))) AND (date < (lead((generate_series('2024-09-01 00:00:01+00'::timestamp with time zone, '2024-09-13 23:59:59+00'::timestamp with time zone, ('10800000 milliseconds'::cstring)::interval))) OVER (?))) AND (date >= '2024-09-01 00:00:01'::timestamp without time zone) AND (date <= '2024-09-13 23:59:59'::timestamp without time zone))
                                                         Filter: ((battery_level IS NOT NULL) AND (car_id = 1))
   SubPlan 1
     ->  Aggregate  (cost=0.16..0.17 rows=1 width=8) (actual time=0.471..0.471 rows=1 loops=104)
           ->  Function Scan on unnest trick_1  (cost=0.00..0.10 rows=10 width=32) (actual time=0.072..0.121 rows=104 loops=104)
   SubPlan 2
     ->  Aggregate  (cost=0.16..0.17 rows=1 width=8) (actual time=0.472..0.472 rows=1 loops=104)
           ->  Function Scan on unnest trick_2  (cost=0.00..0.10 rows=10 width=32) (actual time=0.072..0.121 rows=104 loops=104)
   SubPlan 3
     ->  Aggregate  (cost=0.16..0.17 rows=1 width=8) (actual time=0.475..0.476 rows=1 loops=104)
           ->  Function Scan on unnest trick_3  (cost=0.00..0.10 rows=10 width=32) (actual time=0.072..0.121 rows=104 loops=104)
 Planning Time: 15.153 ms
 JIT:
   Functions: 57
   Options: Inlining false, Optimization false, Expressions true, Deforming true
   Timing: Generation 22.986 ms, Inlining 0.000 ms, Optimization 32.070 ms, Emission 507.753 ms, Total 562.809 ms
 Execution Time: 4231.983 ms
(36 rows)

(END)

Which is more than 3x faster than without index, innit? :-)

And without EXPLAIN ANALYZE

      series_id        |       p0075        |       p050        |       p0925
------------------------+--------------------+-------------------+-------------------
 2024-09-01 00:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-01 03:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-01 06:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-01 09:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-01 12:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-01 15:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-01 18:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-01 21:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-02 00:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-02 03:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-02 06:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-02 09:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-02 12:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-02 15:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-02 18:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-02 21:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-03 00:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-03 03:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-03 06:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-03 09:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-03 12:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-03 15:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-03 18:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-03 21:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-04 00:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-04 03:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-04 06:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-04 09:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-04 12:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-04 15:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-04 18:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-04 21:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-05 00:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-05 03:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-05 06:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-05 09:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-05 12:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-05 15:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-05 18:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-05 21:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-06 00:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-06 03:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-06 06:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-06 09:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-06 12:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-06 15:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-06 18:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-06 21:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-07 00:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-07 03:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-07 06:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-07 09:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-07 12:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-07 15:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-07 18:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-07 21:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-08 00:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-08 03:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-08 06:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-08 09:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-08 12:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
2024-09-08 15:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-08 18:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-08 21:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-09 00:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-09 03:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-09 06:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-09 09:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-09 12:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-09 15:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-09 18:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-09 21:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-10 00:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-10 03:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-10 06:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-10 09:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-10 12:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-10 15:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-10 18:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-10 21:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-11 00:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-11 03:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-11 06:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-11 09:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-11 12:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-11 15:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-11 18:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-11 21:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-12 00:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-12 03:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-12 06:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-12 09:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-12 12:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-12 15:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-12 18:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-12 21:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-13 00:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-13 03:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-13 06:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-13 09:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-13 12:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-13 15:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-13 18:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
 2024-09-13 21:00:01+00 | 51.863056885892945 | 63.16666666666667 | 76.03816586777607
(104 rows)

(END)

@JakobLichterfeld
Copy link
Collaborator

JakobLichterfeld commented Sep 15, 2024

Yeah, with a quick look into the migrations, I could not find one for positions_date_index for example.

I assume, this one should normally create the index (introduced by #3186):
https://github.com/teslamate-org/teslamate/blob/363e5a661612a090cfac5bf89715f7e9de39f420/priv/repo/migrations/20230417225712_composite_index_to_position.exs

@JakobLichterfeld
Copy link
Collaborator

JakobLichterfeld commented Sep 15, 2024

Btw. love the speed on the Rpi 3B with the 6 additional indexes 😃
Only small finding in #4199

@swiffer
Copy link
Contributor Author

swiffer commented Sep 15, 2024

great to hear, wonder if i might should switch to slower hardware and look for additional improvements by adding an index here and there 😆

finalized the query for charge level - works great here

@JakobLichterfeld - could you first add an index:

CREATE INDEX "positions_car_id_date_ideal_battery_range_km_IS_NOT_NULL_index" ON public.positions USING btree (car_id, date, ((ideal_battery_range_km IS NOT NULL))) WHERE (ideal_battery_range_km IS NOT NULL)

and afterwards run this query:

-- To be able to calucate percentiles for unevenly sampled values we are bucketing & gapfilling values before running calcuations
explain analyze with positions_filtered as (
    select
        date,
        battery_level
    from
        positions p
    where
        p.car_id = '1'
        -- p.ideal_battery_range_km condition is added to reduce overall amount of data and avoid data biases while driving (unevenly sampled data)
        and p.ideal_battery_range_km is not null
),
gen_date_series as (
    select
        -- series is used to bucket data and avoid gaps in series used to determine percentiles
        generate_series(to_timestamp(1710497281), to_timestamp(1726391281), concat(7200, ' seconds')::interval) as series_id
),
date_series as (
    select
        series_id,
        -- before joining, get beginning of next series to be able to left join `positions_filtered`
        lead(series_id) over (order by series_id asc) as next_series_id
    from
        gen_date_series
),
positions_bucketed as (
    select
        series_id,
        -- simple average can result in loss of accuracy, see https://www.timescale.com/blog/what-time-weighted-averages-are-and-why-you-should-care/ for details
        avg(battery_level) as battery_level
    from
        date_series
    left join positions_filtered on
        positions_filtered.date >= date_series.series_id
        and positions_filtered.date < date_series.next_series_id
    group by
        series_id
),
-- PostgreSQL cannot IGNORE NULLS via Window Functions LAST_VALUE - therefore use natural behavior of COUNT & MAX, see https://www.reddit.com/r/SQL/comments/wb949v/comment/ii5mmmi/ for details
positions_bucketed_gapfilling_locf_intermediate as (
    select
        series_id,
        battery_level,
        count(battery_level) over (order by series_id) as i
    from
        positions_bucketed

),
positions_bucketed_gapfilled_locf as (
    select
        series_id,
        max(battery_level) over (partition by i) as battery_level
    from
        positions_bucketed_gapfilling_locf_intermediate
),
-- PostgreSQL cannot use PERCENTILE_DISC as Window Function - therefore use ARRAY_AGG and UNNEST, see https://stackoverflow.com/a/72718604 for details
positions_bucketed_gapfilled_locf_percentile_intermediate as (
    select
        series_id,
        battery_level,
        array_agg(battery_level) over w as arr,
        avg(battery_level) over w as battery_level_avg
    from
        positions_bucketed_gapfilled_locf
    window w as (rows between (1296000 / 7200) preceding and (1296000 / 7200) following)
)

select
    series_id,
    case when battery_level is null then null else (select percentile_cont(0.075) within group (order by s) from unnest(arr) trick(s)) end as "30 Day Moving 7,5% Percentile",
    case when battery_level is null then null else (battery_level_avg) end as "30 Day Moving Average",
    case when battery_level is null then null else (select percentile_cont(0.5) within group (order by s) from unnest(arr) trick(s)) end as "30 Day Moving Median",
    case when battery_level is null then null else (select percentile_cont(0.925) within group (order by s) from unnest(arr) trick(s)) end as "30 Day Moving 92,5% Percentile"
from
    positions_bucketed_gapfilled_locf_percentile_intermediate;

@JakobLichterfeld
Copy link
Collaborator

JakobLichterfeld commented Sep 15, 2024

great to hear, wonder if i might should switch to slower hardware and look for additional improvements by adding an index here and there 😆

😄 I only found a slow query after that, see #4199

could you first add an index:

Created with ; at the end

and afterwards run this query:

                                                                                                                                                                                                                                 QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Subquery Scan on positions_bucketed_gapfilled_locf_percentile_intermediate  (cost=1556588.22..1556695.72 rows=200 width=64) (actual time=7442.816..17583.645 rows=2208 loops=1)
   ->  WindowAgg  (cost=1556588.22..1556596.72 rows=200 width=104) (actual time=7442.779..8347.987 rows=2208 loops=1)
         ->  Subquery Scan on positions_bucketed_gapfilled_locf  (cost=1556588.22..1556593.72 rows=200 width=40) (actual time=3659.174..3675.169 rows=2208 loops=1)
               ->  WindowAgg  (cost=1556588.22..1556591.72 rows=200 width=48) (actual time=3659.142..3672.381 rows=2208 loops=1)
                     ->  Sort  (cost=1556588.22..1556588.72 rows=200 width=48) (actual time=3658.844..3660.370 rows=2208 loops=1)
                           Sort Key: positions_bucketed_gapfilling_locf_intermediate.i
                           Sort Method: quicksort  Memory: 155kB
                           ->  Subquery Scan on positions_bucketed_gapfilling_locf_intermediate  (cost=55.28..1556580.57 rows=200 width=48) (actual time=8.954..3653.613 rows=2208 loops=1)
                                 ->  WindowAgg  (cost=55.28..1556580.57 rows=200 width=48) (actual time=8.934..3650.616 rows=2208 loops=1)
                                       ->  GroupAggregate  (cost=55.28..1556577.57 rows=200 width=40) (actual time=8.802..3632.143 rows=2208 loops=1)
                                             Group Key: (generate_series('2024-03-15 10:08:01+00'::timestamp with time zone, '2024-09-15 09:08:01+00'::timestamp with time zone, (concat(7200, ' seconds'))::interval))
                                             ->  Nested Loop Left Join  (cost=55.28..1392872.85 rows=32740444 width=10) (actual time=8.643..3598.592 rows=22537 loops=1)
                                                   ->  WindowAgg  (cost=54.85..72.35 rows=1000 width=16) (actual time=4.922..24.914 rows=2208 loops=1)
                                                         ->  Sort  (cost=54.85..57.35 rows=1000 width=8) (actual time=4.778..7.353 rows=2208 loops=1)
                                                               Sort Key: (generate_series('2024-03-15 10:08:01+00'::timestamp with time zone, '2024-09-15 09:08:01+00'::timestamp with time zone, (concat(7200, ' seconds'))::interval))
                                                               Sort Method: quicksort  Memory: 99kB
                                                               ->  ProjectSet  (cost=0.00..5.03 rows=1000 width=8) (actual time=0.207..3.379 rows=2208 loops=1)
                                                                     ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual time=0.026..0.028 rows=1 loops=1)
                                                   ->  Index Scan using "positions_car_id_date_ideal_battery_range_km_IS_NOT_NULL_index" on positions p  (cost=0.42..1065.40 rows=32740 width=10) (actual time=0.070..1.600 rows=9 loops=2208)
                                                         Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 10:08:01+00'::timestamp with time zone, '2024-09-15 09:08:01+00'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 10:08:01+00'::timestamp with time zone, '2024-09-15 09:08:01+00'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
   SubPlan 1
     ->  Aggregate  (cost=0.16..0.17 rows=1 width=8) (actual time=1.418..1.419 rows=1 loops=2187)
           ->  Function Scan on unnest trick  (cost=0.00..0.10 rows=10 width=32) (actual time=0.229..0.397 rows=348 loops=2187)
   SubPlan 2
     ->  Aggregate  (cost=0.16..0.17 rows=1 width=8) (actual time=1.393..1.393 rows=1 loops=2187)
           ->  Function Scan on unnest trick_1  (cost=0.00..0.10 rows=10 width=32) (actual time=0.232..0.399 rows=348 loops=2187)
   SubPlan 3
     ->  Aggregate  (cost=0.16..0.17 rows=1 width=8) (actual time=1.389..1.389 rows=1 loops=2187)
           ->  Function Scan on unnest trick_2  (cost=0.00..0.10 rows=10 width=32) (actual time=0.230..0.396 rows=348 loops=2187)
 Planning Time: 30.443 ms
 JIT:
   Functions: 57
   Options: Inlining true, Optimization true, Expressions true, Deforming true
   Timing: Generation 23.334 ms, Inlining 775.072 ms, Optimization 1706.078 ms, Emission 1301.190 ms, Total 3805.675 ms
 Execution Time: 21119.696 ms
(35 rows)

(END)

and output seems reasonable

@sdwalker
Copy link
Contributor

@coreGreenberet / @sdwalker - can you confirm a total of 36 indexes within your environments of teslamate via select count(*) from pg_indexes where schemaname = 'public';

Yes

teslamate=# select count(*) from pg_indexes where schemaname = 'public';
 count
-------
    36
(1 row)

@swiffer
Copy link
Contributor Author

swiffer commented Sep 15, 2024

closed in favor of #4200

@JakobLichterfeld - should we take any action for missing potentially missing indexes on other instances?

@swiffer swiffer closed this Sep 15, 2024
@swiffer swiffer deleted the charge-level-regression-line branch September 15, 2024 17:49
@JakobLichterfeld
Copy link
Collaborator

@JakobLichterfeld - should we take any action for missing potentially missing indexes on other instances?

Yeah, let's track it in #4201

@coreGreenberet
Copy link
Contributor

coreGreenberet commented Sep 16, 2024

@JakobLichterfeld
@coreGreenberet can you confirm a total of 36 indexes within your environments of teslamate via select count(*) from pg_indexes where schemaname = 'public';

actually I'm having 640 😁 - Edit: 48 without the partion positions_YYMM tables
I've partitioned the positions table and I've also added my own indexes.
Each line got skipped from your create index snippet.

@swiffer
Copy link
Contributor Author

swiffer commented Sep 16, 2024

Ok, that doesnt help. If there are indexes that are benefitial for all please feel free to open an issue / pr!

Why have you partioned the positions table, also to speed up queries ?

@JakobLichterfeld would be another argument for switching to timescaledb ;) partitions by default ...

@coreGreenberet
Copy link
Contributor

coreGreenberet commented Sep 16, 2024

@swiffer I've overseen your new index "positions_car_id_date_ideal_battery_range_km_IS_NOT_NULL_index", but that didn't really speed up the process and for whatever reason the query now takes ~1:30 minutes

yes I've partitioned it for performance reasons. ATM positions has 15232196 entries which are ~6.4GB of data

  ->  WindowAgg  (cost=2896960.72..2896969.22 rows=200 width=104) (actual time=81261.158..82345.559 rows=2208 loops=1)
        ->  Subquery Scan on positions_bucketed_gapfilled_locf  (cost=2896960.72..2896966.22 rows=200 width=40) (actual time=3557.887..3592.829 rows=2208 loops=1)
              ->  WindowAgg  (cost=2896960.72..2896964.22 rows=200 width=48) (actual time=3557.879..3587.942 rows=2208 loops=1)
                    ->  Sort  (cost=2896960.72..2896961.22 rows=200 width=48) (actual time=3557.792..3560.490 rows=2208 loops=1)
                          Sort Key: positions_bucketed_gapfilling_locf_intermediate.i
                          Sort Method: quicksort  Memory: 237kB
                          ->  Subquery Scan on positions_bucketed_gapfilling_locf_intermediate  (cost=65.13..2896953.07 rows=200 width=48) (actual time=17.731..3548.622 rows=2208 loops=1)
                                ->  WindowAgg  (cost=65.13..2896951.07 rows=200 width=48) (actual time=17.726..3545.956 rows=2208 loops=1)
                                      ->  GroupAggregate  (cost=65.13..2896946.07 rows=200 width=40) (actual time=13.623..3523.621 rows=2208 loops=1)
                                            Group Key: (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))
                                            ->  Nested Loop Left Join  (cost=65.13..2649826.35 rows=49423444 width=10) (actual time=9.746..3429.550 rows=86435 loops=1)
                                                  ->  WindowAgg  (cost=64.85..82.35 rows=1000 width=16) (actual time=1.769..24.437 rows=2208 loops=1)
                                                        ->  Sort  (cost=64.85..67.35 rows=1000 width=8) (actual time=1.704..4.458 rows=2208 loops=1)
                                                              Sort Key: (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))
                                                              Sort Method: quicksort  Memory: 200kB
                                                              ->  ProjectSet  (cost=0.00..5.03 rows=1000 width=8) (actual time=0.070..0.810 rows=2208 loops=1)
                                                                    ->  Result  (cost=0.00..0.01 rows=1 width=0) (actual time=0.009..0.010 rows=1 loops=1)
                                                  ->  Append  (cost=0.28..2155.08 rows=49465 width=10) (actual time=0.113..1.432 rows=39 loops=2208)
                                                        ->  Index Scan using positions_2112_car_id_date_expr_idx on positions_2112 p  (cost=0.28..15.88 rows=413 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2201_car_id_date_expr_idx on positions_2201 p_1  (cost=0.28..32.97 rows=806 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2202_car_id_date_expr_idx on positions_2202 p_2  (cost=0.28..26.22 rows=620 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2203_car_id_date_expr_idx on positions_2203 p_3  (cost=0.28..37.30 rows=879 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2204_car_id_date_expr_idx on positions_2204 p_4  (cost=0.29..49.64 rows=1230 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2205_car_id_date_expr_idx on positions_2205 p_5  (cost=0.29..40.28 rows=1028 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2206_car_id_date_expr_idx on positions_2206 p_6  (cost=0.29..43.13 rows=1159 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2207_car_id_date_expr_idx on positions_2207 p_7  (cost=0.29..46.20 rows=1234 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2208_car_id_date_expr_idx on positions_2208 p_8  (cost=0.29..73.01 rows=2366 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2209_car_id_date_expr_idx on positions_2209 p_9  (cost=0.29..47.00 rows=1257 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2210_car_id_date_expr_idx on positions_2210 p_10  (cost=0.29..34.58 rows=916 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2211_car_id_date_expr_idx on positions_2211 p_11  (cost=0.29..79.53 rows=1971 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2212_car_id_date_expr_idx on positions_2212 p_12  (cost=0.29..44.53 rows=1276 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2301_car_id_date_expr_idx on positions_2301 p_13  (cost=0.29..54.92 rows=1364 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2302_car_id_date_expr_idx on positions_2302 p_14  (cost=0.29..64.78 rows=1609 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2303_car_id_date_expr_idx on positions_2303 p_15  (cost=0.29..74.45 rows=1952 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2304_car_id_date_expr_idx on positions_2304 p_16  (cost=0.29..67.78 rows=1759 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2305_car_id_date_expr_idx on positions_2305 p_17  (cost=0.29..62.13 rows=1543 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2306_car_id_date_expr_idx on positions_2306 p_18  (cost=0.29..73.30 rows=1975 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2307_car_id_date_expr_idx on positions_2307 p_19  (cost=0.29..78.54 rows=2250 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2308_car_id_date_expr_idx on positions_2308 p_20  (cost=0.29..71.83 rows=1908 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2309_car_id_date_expr_idx on positions_2309 p_21  (cost=0.29..54.00 rows=1350 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2310_car_id_date_expr_idx on positions_2310 p_22  (cost=0.29..62.35 rows=1617 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2311_car_id_date_expr_idx on positions_2311 p_23  (cost=0.29..79.34 rows=2412 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2312_car_id_date_expr_idx on positions_2312 p_24  (cost=0.29..58.84 rows=1492 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2401_car_id_date_expr_idx on positions_2401 p_25  (cost=0.29..57.76 rows=1426 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2402_car_id_date_expr_idx on positions_2402 p_26  (cost=0.29..62.63 rows=1501 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2403_car_id_date_expr_idx on positions_2403 p_27  (cost=0.29..54.77 rows=1352 width=10) (actual time=0.089..0.585 rows=31 loops=198)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2404_car_id_date_expr_idx on positions_2404 p_28  (cost=0.29..61.63 rows=1492 width=10) (actual time=0.063..1.567 rows=38 loops=361)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2405_car_id_date_expr_idx on positions_2405 p_29  (cost=0.29..65.20 rows=1673 width=10) (actual time=0.087..1.524 rows=40 loops=373)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2406_car_id_date_expr_idx on positions_2406 p_30  (cost=0.29..59.82 rows=1526 width=10) (actual time=0.106..1.477 rows=39 loops=361)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2407_car_id_date_expr_idx on positions_2407 p_31  (cost=0.29..64.48 rows=1595 width=10) (actual time=0.112..1.886 rows=40 loops=373)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2408_car_id_date_expr_idx on positions_2408 p_32  (cost=0.29..64.40 rows=1620 width=10) (actual time=0.086..1.038 rows=40 loops=373)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2409_car_id_date_expr_idx on positions_2409 p_33  (cost=0.28..34.59 rows=842 width=10) (actual time=0.099..1.036 rows=42 loops=174)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2410_car_id_date_expr_idx on positions_2410 p_34  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2411_car_id_date_expr_idx on positions_2411 p_35  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2412_car_id_date_expr_idx on positions_2412 p_36  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2501_car_id_date_expr_idx on positions_2501 p_37  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2502_car_id_date_expr_idx on positions_2502 p_38  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2503_car_id_date_expr_idx on positions_2503 p_39  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2504_car_id_date_expr_idx on positions_2504 p_40  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2505_car_id_date_expr_idx on positions_2505 p_41  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2506_car_id_date_expr_idx on positions_2506 p_42  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2507_car_id_date_expr_idx on positions_2507 p_43  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2508_car_id_date_expr_idx on positions_2508 p_44  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2509_car_id_date_expr_idx on positions_2509 p_45  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2510_car_id_date_expr_idx on positions_2510 p_46  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2511_car_id_date_expr_idx on positions_2511 p_47  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2512_car_id_date_expr_idx on positions_2512 p_48  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2601_car_id_date_expr_idx on positions_2601 p_49  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2602_car_id_date_expr_idx on positions_2602 p_50  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2603_car_id_date_expr_idx on positions_2603 p_51  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2604_car_id_date_expr_idx on positions_2604 p_52  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2605_car_id_date_expr_idx on positions_2605 p_53  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2606_car_id_date_expr_idx on positions_2606 p_54  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2607_car_id_date_expr_idx on positions_2607 p_55  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2608_car_id_date_expr_idx on positions_2608 p_56  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2609_car_id_date_expr_idx on positions_2609 p_57  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2610_car_id_date_expr_idx on positions_2610 p_58  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2611_car_id_date_expr_idx on positions_2611 p_59  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2612_car_id_date_expr_idx on positions_2612 p_60  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2701_car_id_date_expr_idx on positions_2701 p_61  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2702_car_id_date_expr_idx on positions_2702 p_62  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2703_car_id_date_expr_idx on positions_2703 p_63  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2704_car_id_date_expr_idx on positions_2704 p_64  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2705_car_id_date_expr_idx on positions_2705 p_65  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2706_car_id_date_expr_idx on positions_2706 p_66  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2707_car_id_date_expr_idx on positions_2707 p_67  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2708_car_id_date_expr_idx on positions_2708 p_68  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2709_car_id_date_expr_idx on positions_2709 p_69  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2710_car_id_date_expr_idx on positions_2710 p_70  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2711_car_id_date_expr_idx on positions_2711 p_71  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2712_car_id_date_expr_idx on positions_2712 p_72  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2801_car_id_date_expr_idx on positions_2801 p_73  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2802_car_id_date_expr_idx on positions_2802 p_74  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2803_car_id_date_expr_idx on positions_2803 p_75  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2804_car_id_date_expr_idx on positions_2804 p_76  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2805_car_id_date_expr_idx on positions_2805 p_77  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2806_car_id_date_expr_idx on positions_2806 p_78  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2807_car_id_date_expr_idx on positions_2807 p_79  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2808_car_id_date_expr_idx on positions_2808 p_80  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2809_car_id_date_expr_idx on positions_2809 p_81  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2810_car_id_date_expr_idx on positions_2810 p_82  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2811_car_id_date_expr_idx on positions_2811 p_83  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_2812_car_id_date_expr_idx on positions_2812 p_84  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
                                                        ->  Index Scan using positions_default_car_id_date_expr_idx on positions_default p_85  (cost=0.12..0.19 rows=1 width=10) (never executed)
                                                              Index Cond: ((car_id = '1'::smallint) AND (date >= (generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) AND (date < (lead((generate_series('2024-03-15 11:08:01+01'::timestamp with time zone, '2024-09-15 11:08:01+02'::timestamp with time zone, (concat(7200, ' seconds'))::interval))) OVER (?))))
  SubPlan 1
    ->  Aggregate  (cost=0.16..0.17 rows=1 width=8) (actual time=1.765..1.766 rows=1 loops=2208)
          ->  Function Scan on unnest trick  (cost=0.00..0.10 rows=10 width=32) (actual time=0.265..0.388 rows=346 loops=2208)
  SubPlan 2
    ->  Aggregate  (cost=0.16..0.17 rows=1 width=8) (actual time=1.749..1.749 rows=1 loops=2208)
          ->  Function Scan on unnest trick_1  (cost=0.00..0.10 rows=10 width=32) (actual time=0.264..0.390 rows=346 loops=2208)
  SubPlan 3
    ->  Aggregate  (cost=0.16..0.17 rows=1 width=8) (actual time=1.765..1.765 rows=1 loops=2208)
          ->  Function Scan on unnest trick_2  (cost=0.00..0.10 rows=10 width=32) (actual time=0.265..0.400 rows=346 loops=2208)
Planning Time: 152.184 ms
JIT:
  Functions: 570
  Options: Inlining true, Optimization true, Expressions true, Deforming true
  Timing: Generation 598.691 ms, Inlining 257.288 ms, Optimization 50413.348 ms, Emission 26995.150 ms, Total 78264.477 ms
Execution Time: 94728.314 ms

@swiffer
Copy link
Contributor Author

swiffer commented Sep 16, 2024

@coreGreenberet - could you try the updated dashboard provided in grafana image of #4200 ?

@coreGreenberet
Copy link
Contributor

coreGreenberet commented Sep 16, 2024

@swiffer
grafik

@swiffer
Copy link
Contributor Author

swiffer commented Sep 17, 2024

@coreGreenberet thanks, seems reasonable when comparing to timing from jakob

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area:dashboard Related to a Grafana dashboard
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants