Skip to main content
Add update on solution.
Source Link

Update Though I am still not happy with the row estimates, I found the root issue. The student_snapshot table used text for student_id while the other two used citext. We recently updated student_snapshot to also be citext so that they all matched. I don't understand why it used a better query plan back when they mismatched but in comparing query plans I saw that it was doing snp.student_id = t.student_id::text. When I altered the query to snp.student_id::text = t.student_id::text it became fast again. Seems a bit counterintuitive since the conversion should be less efficient, but it led to a much better query plan even though the row estimate was still terribly off. It uses a Parallel Hash Join instead of a Nested Loop. Sorry I didn't provide enough context for this earlier.

Update Though I am still not happy with the row estimates, I found the root issue. The student_snapshot table used text for student_id while the other two used citext. We recently updated student_snapshot to also be citext so that they all matched. I don't understand why it used a better query plan back when they mismatched but in comparing query plans I saw that it was doing snp.student_id = t.student_id::text. When I altered the query to snp.student_id::text = t.student_id::text it became fast again. Seems a bit counterintuitive since the conversion should be less efficient, but it led to a much better query plan even though the row estimate was still terribly off. It uses a Parallel Hash Join instead of a Nested Loop. Sorry I didn't provide enough context for this earlier.

Changes `rating` to `test` for consistency
Source Link

The query is more complex than this but I can create a minimal reproducible example from the essenseessence of these three tables:

select rt.*, st.grade_id as current_grade_id, snp.grade_id as snapshot_grade_id
from student st
join ratingtest rt
  on rt.student_id = st.student_id
join student_snapshot snp
  on snp.student_id = rt.student_id
  and snp.created_at = rt.student_snapshot_date

The query was taking < 1s but can now take upwards of 2hrs after a recent infusion of data into the database (~50% increase). The performance did not degrade linearly as the volume increased. It appears to have changed the normal query plan which now uses a Nested Loop. It appears to be making this choice because it expects the row count to be 2 when it is really closer to 90k. I find it interesting that when I leave off the and snp.created_at = rt.student_snapshot_date condition that the query plan has a reasonable expectation of the number of rows returned and does not choose a Nested Loop.

QUERY PLAN                                                                                                                                                                                                                                                 |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Nested Loop  (cost=2044.29..6432.12 rows=2 width=10) (actual time=65.097..1904659.897 rows=72902 loops=1)                                                                                                                                                  |
  Output: st.student_id                                                                                                                                                                                                                                    |
  Buffers: shared hit=34879380                                                                                                                                                                                                                             |
  ->  Hash Join  (cost=2043.88..5769.94 rows=2 width=20) (actual time=41.050..955.542 rows=90631 loops=1)                                                                                                                                                  |
        Output: rt.student_id, snp.student_id                                                                                                                                                                                                               |
        Hash Cond: ((rt.student_id = snp.student_id) AND (rt.student_snapshot_date = snp.created_at))                                                                                                                                                        |
        Buffers: shared hit=3015                                                                                                                                                                                                                           |
        ->  Seq Scan on public."rating""test" rt  (cost=0.00..3046.31 rows=90631 width=18) (actual time=0.010..169.664 rows=90631 loops=1)                                                                                 |
              Output: rt.id, r.program_id, r.organization_id, r.assessment_type_id, r.rater_type_id, r.t_score, r.created_at, r.duration, r.rater_email, r.assignment_period, rt.student_id, r.student_snapshot_date, r.descriptive_range_id, rt.language_code|student_snapshot_date|
              Buffers: shared hit=2140                                                                                                                                                                                                                     |
        ->  Hash  (cost=1342.55..1342.55 rows=46755 width=18) (actual time=39.342..39.343 rows=46755 loops=1)                                                                                                                                              |
              Output: snp.student_id, snp.created_at                                                                                                                                                                                                       |
              Buckets: 65536  Batches: 1  Memory Usage: 3069kB                                                                                                                                                                                             |
              Buffers: shared hit=875                                                                                                                                                                                                                      |
              ->  Seq Scan on public."student_snapshot" snp  (cost=0.00..1342.55 rows=46755 width=18) (actual time=0.018..13.942 rows=46755 loops=1)                                                                |
                    Output: snp.student_id, snp.created_at                                                                                                                                                                                                 |
                    Buffers: shared hit=875                                                                                                                                                                                                                |
  ->  Index Only Scan using "student_key" on public."student" st  (cost=0.41..331.08 rows=1 width=10) (actual time=12.086..21.000 rows=1 loops=90631)           |
        Output: st.program_id, st.organization_id, st.student_id                                                                                                                                                                                           |
        Index Cond: (st.student_id = rt.student_id)                                                                                                                                                                                                         |
        Heap Fetches: 74061                                                                                                                                                                                                                                |
        Buffers: shared hit=34876365                                                                                                                                                                                                                       |
Planning:                                                                                                                                                                                                                                                  |
  Buffers: shared hit=40                                                                                                                                                                                                                                   |
Planning Time: 1.063 ms                                                                                                                                                                                                                                    |
Execution Time: 1904722.476 ms                                                                                                                                                                                                                             |
QUERY PLAN                                                                                                                                                                                                                                           |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Hash Join  (cost=4254.08..8568.10 rows=92784 width=10) (actual time=114.921..219.856 rows=74332 loops=1)                                                                                                                                             |
  Output: st.student_id                                                                                                                                                                                                                              |
  Hash Cond: (rt.student_id = st.student_id)                                                                                                                                                                                                          |
  Buffers: shared hit=3744                                                                                                                                                                                                                           |
  ->  Seq Scan on public."rating""test" rt  (cost=0.00..3046.31 rows=90631 width=10) (actual time=0.010..12.670 rows=90631 loops=1)                                                                                  |
        Output: rt.id, r.program_id, r.organization_id, r.assessment_type_id, r.rater_type_id, r.t_score, r.created_at, r.duration, r.rater_email, r.assignment_period, rt.student_id, r.student_snapshot_date, r.descriptive_range_id, rt.language_code|student_snapshot_date|
        Buffers: shared hit=2140                                                                                                                                                                                                                     |
  ->  Hash  (cost=3689.98..3689.98 rows=45128 width=20) (actual time=114.737..114.739 rows=36995 loops=1)                                                                                                                                            |
        Output: st.student_id, snp.student_id                                                                                                                                                                                                        |
        Buckets: 65536  Batches: 1  Memory Usage: 2391kB                                                                                                                                                                                             |
        Buffers: shared hit=1604                                                                                                                                                                                                                     |
        ->  Hash Join  (cost=1720.82..3689.98 rows=45128 width=20) (actual time=33.975..95.906 rows=36995 loops=1)                                                                                                                                   |
              Output: st.student_id, snp.student_id                                                                                                                                                                                                  |
              Hash Cond: (snp.student_id = st.student_id)                                                                                                                                                                                            |
              Buffers: shared hit=1604                                                                                                                                                                                                               |
              ->  Seq Scan on public."student_snapshot" snp  (cost=0.00..1342.55 rows=46755 width=10) (actual time=0.030..13.741 rows=46755 loops=1)                                                          |
                    Output: snp.student_id, snp.created_at, snp.program_id, snp.organization_id, snp.first_name, snp.last_name, snp.gender_id, snp.grade_id, snp.date_of_birth, snp.race, snp.academic, snp.zip, snp.state_id                        |
                    Buffers: shared hit=875                                                                                                                                                                                                          |
              ->  Hash  (cost=1169.81..1169.81 rows=44081 width=10) (actual time=31.513..31.514 rows=43262 loops=1)                                                                                                                                  |
                    Output: st.student_id                                                                                                                                                                                                            |
                    Buckets: 65536  Batches: 1  Memory Usage: 2287kB                                                                                                                                                                                 |
                    Buffers: shared hit=729                                                                                                                                                                                                          |
                    ->  Seq Scan on public."student" st  (cost=0.00..1169.81 rows=44081 width=10) (actual time=0.015..10.926 rows=43262 loops=1)                                                              |
                          Output: st.student_id                                                                                                                                                                                                      |
                          Buffers: shared hit=729                                                                                                                                                                                                    |
Planning:                                                                                                                                                                                                                                            |
  Buffers: shared hit=40                                                                                                                                                                                                                             |
Planning Time: 1.042 ms                                                                                                                                                                                                                              |
Execution Time: 223.517 ms                                                                                                                                                                                                                           |
CREATE STATISTICS "rating_st_snp_pk""test_st_snp_pk" ON student_id, student_snapshot_date FROM "rating";"test";
CREATE STATISTICS "st_snp_pk" ON student_id, created_at FROM "student_snapshot";
alter table "rating""test" alter student_id set statistics 500;
alter table "rating""test" alter student_snapshot_date set statistics 500;
alter table "student_snapshot" alter student_id set statistics 500;
alter table "student_snapshot" alter created_at set statistics 500;

I tried clustering on a parallel indexes for ratingtest and student_snapshot to see if it would find more hits if they were sorted the same:

cluster "rating""test" using "rating__student_id_student_snapshot_date_idx";"test_student_id_student_snapshot_date_idx";
cluster "student_snapshot" using "student_snapshot_pkey";
with rating_w_snaptest_w_snap as materialized (
  select rt.*, snp.grade_id
  from ratingtest rt
  join student_snapshot snp
    on snp.student_id = rt.student_id
    and snp.created_at = rt.student_snapshot_date
)
select rt.*, st.grade_id as current_grade_id, rt.grade_id as snapshot_grade_id
from student st
join rating_w_snaptest_w_snap rt
  on rt.student_id = st.student_id

The query is more complex than this but I can create a minimal reproducible example from the essense of these three tables:

select r.*, st.grade_id as current_grade_id, snp.grade_id as snapshot_grade_id
from student st
join rating r
  on r.student_id = st.student_id
join student_snapshot snp
  on snp.student_id = r.student_id
  and snp.created_at = r.student_snapshot_date

The query was taking < 1s but can now take upwards of 2hrs after a recent infusion of data into the database (~50% increase). The performance did not degrade linearly as the volume increased. It appears to have changed the normal query plan which now uses a Nested Loop. It appears to be making this choice because it expects the row count to be 2 when it is really closer to 90k. I find it interesting that when I leave off the and snp.created_at = r.student_snapshot_date condition that the query plan has a reasonable expectation of the number of rows returned and does not choose a Nested Loop.

QUERY PLAN                                                                                                                                                                                                                                                 |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Nested Loop  (cost=2044.29..6432.12 rows=2 width=10) (actual time=65.097..1904659.897 rows=72902 loops=1)                                                                                                                                                  |
  Output: st.student_id                                                                                                                                                                                                                                    |
  Buffers: shared hit=34879380                                                                                                                                                                                                                             |
  ->  Hash Join  (cost=2043.88..5769.94 rows=2 width=20) (actual time=41.050..955.542 rows=90631 loops=1)                                                                                                                                                  |
        Output: r.student_id, snp.student_id                                                                                                                                                                                                               |
        Hash Cond: ((r.student_id = snp.student_id) AND (r.student_snapshot_date = snp.created_at))                                                                                                                                                        |
        Buffers: shared hit=3015                                                                                                                                                                                                                           |
        ->  Seq Scan on public."rating" r  (cost=0.00..3046.31 rows=90631 width=18) (actual time=0.010..169.664 rows=90631 loops=1)                                                                                 |
              Output: r.id, r.program_id, r.organization_id, r.assessment_type_id, r.rater_type_id, r.t_score, r.created_at, r.duration, r.rater_email, r.assignment_period, r.student_id, r.student_snapshot_date, r.descriptive_range_id, r.language_code|
              Buffers: shared hit=2140                                                                                                                                                                                                                     |
        ->  Hash  (cost=1342.55..1342.55 rows=46755 width=18) (actual time=39.342..39.343 rows=46755 loops=1)                                                                                                                                              |
              Output: snp.student_id, snp.created_at                                                                                                                                                                                                       |
              Buckets: 65536  Batches: 1  Memory Usage: 3069kB                                                                                                                                                                                             |
              Buffers: shared hit=875                                                                                                                                                                                                                      |
              ->  Seq Scan on public."student_snapshot" snp  (cost=0.00..1342.55 rows=46755 width=18) (actual time=0.018..13.942 rows=46755 loops=1)                                                                |
                    Output: snp.student_id, snp.created_at                                                                                                                                                                                                 |
                    Buffers: shared hit=875                                                                                                                                                                                                                |
  ->  Index Only Scan using "student_key" on public."student" st  (cost=0.41..331.08 rows=1 width=10) (actual time=12.086..21.000 rows=1 loops=90631)           |
        Output: st.program_id, st.organization_id, st.student_id                                                                                                                                                                                           |
        Index Cond: (st.student_id = r.student_id)                                                                                                                                                                                                         |
        Heap Fetches: 74061                                                                                                                                                                                                                                |
        Buffers: shared hit=34876365                                                                                                                                                                                                                       |
Planning:                                                                                                                                                                                                                                                  |
  Buffers: shared hit=40                                                                                                                                                                                                                                   |
Planning Time: 1.063 ms                                                                                                                                                                                                                                    |
Execution Time: 1904722.476 ms                                                                                                                                                                                                                             |
QUERY PLAN                                                                                                                                                                                                                                           |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Hash Join  (cost=4254.08..8568.10 rows=92784 width=10) (actual time=114.921..219.856 rows=74332 loops=1)                                                                                                                                             |
  Output: st.student_id                                                                                                                                                                                                                              |
  Hash Cond: (r.student_id = st.student_id)                                                                                                                                                                                                          |
  Buffers: shared hit=3744                                                                                                                                                                                                                           |
  ->  Seq Scan on public."rating" r  (cost=0.00..3046.31 rows=90631 width=10) (actual time=0.010..12.670 rows=90631 loops=1)                                                                                  |
        Output: r.id, r.program_id, r.organization_id, r.assessment_type_id, r.rater_type_id, r.t_score, r.created_at, r.duration, r.rater_email, r.assignment_period, r.student_id, r.student_snapshot_date, r.descriptive_range_id, r.language_code|
        Buffers: shared hit=2140                                                                                                                                                                                                                     |
  ->  Hash  (cost=3689.98..3689.98 rows=45128 width=20) (actual time=114.737..114.739 rows=36995 loops=1)                                                                                                                                            |
        Output: st.student_id, snp.student_id                                                                                                                                                                                                        |
        Buckets: 65536  Batches: 1  Memory Usage: 2391kB                                                                                                                                                                                             |
        Buffers: shared hit=1604                                                                                                                                                                                                                     |
        ->  Hash Join  (cost=1720.82..3689.98 rows=45128 width=20) (actual time=33.975..95.906 rows=36995 loops=1)                                                                                                                                   |
              Output: st.student_id, snp.student_id                                                                                                                                                                                                  |
              Hash Cond: (snp.student_id = st.student_id)                                                                                                                                                                                            |
              Buffers: shared hit=1604                                                                                                                                                                                                               |
              ->  Seq Scan on public."student_snapshot" snp  (cost=0.00..1342.55 rows=46755 width=10) (actual time=0.030..13.741 rows=46755 loops=1)                                                          |
                    Output: snp.student_id, snp.created_at, snp.program_id, snp.organization_id, snp.first_name, snp.last_name, snp.gender_id, snp.grade_id, snp.date_of_birth, snp.race, snp.academic, snp.zip, snp.state_id                        |
                    Buffers: shared hit=875                                                                                                                                                                                                          |
              ->  Hash  (cost=1169.81..1169.81 rows=44081 width=10) (actual time=31.513..31.514 rows=43262 loops=1)                                                                                                                                  |
                    Output: st.student_id                                                                                                                                                                                                            |
                    Buckets: 65536  Batches: 1  Memory Usage: 2287kB                                                                                                                                                                                 |
                    Buffers: shared hit=729                                                                                                                                                                                                          |
                    ->  Seq Scan on public."student" st  (cost=0.00..1169.81 rows=44081 width=10) (actual time=0.015..10.926 rows=43262 loops=1)                                                              |
                          Output: st.student_id                                                                                                                                                                                                      |
                          Buffers: shared hit=729                                                                                                                                                                                                    |
Planning:                                                                                                                                                                                                                                            |
  Buffers: shared hit=40                                                                                                                                                                                                                             |
Planning Time: 1.042 ms                                                                                                                                                                                                                              |
Execution Time: 223.517 ms                                                                                                                                                                                                                           |
CREATE STATISTICS "rating_st_snp_pk" ON student_id, student_snapshot_date FROM "rating";
CREATE STATISTICS "st_snp_pk" ON student_id, created_at FROM "student_snapshot";
alter table "rating" alter student_id set statistics 500;
alter table "rating" alter student_snapshot_date set statistics 500;
alter table "student_snapshot" alter student_id set statistics 500;
alter table "student_snapshot" alter created_at set statistics 500;

I tried clustering on a parallel indexes for rating and student_snapshot to see if it would find more hits if they were sorted the same:

cluster "rating" using "rating__student_id_student_snapshot_date_idx";
cluster "student_snapshot" using "student_snapshot_pkey";
with rating_w_snap as materialized (
  select r.*, snp.grade_id
  from rating r
  join student_snapshot snp
    on snp.student_id = r.student_id
    and snp.created_at = r.student_snapshot_date
)
select r.*, st.grade_id as current_grade_id, r.grade_id as snapshot_grade_id
from student st
join rating_w_snap r
  on r.student_id = st.student_id

The query is more complex than this but I can create a minimal reproducible example from the essence of these three tables:

select t.*, st.grade_id as current_grade_id, snp.grade_id as snapshot_grade_id
from student st
join test t
  on t.student_id = st.student_id
join student_snapshot snp
  on snp.student_id = t.student_id
  and snp.created_at = t.student_snapshot_date

The query was taking < 1s but can now take upwards of 2hrs after a recent infusion of data into the database (~50% increase). The performance did not degrade linearly as the volume increased. It appears to have changed the normal query plan which now uses a Nested Loop. It appears to be making this choice because it expects the row count to be 2 when it is really closer to 90k. I find it interesting that when I leave off the and snp.created_at = t.student_snapshot_date condition that the query plan has a reasonable expectation of the number of rows returned and does not choose a Nested Loop.

QUERY PLAN                                                                                                                                                                                                                                                 |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Nested Loop  (cost=2044.29..6432.12 rows=2 width=10) (actual time=65.097..1904659.897 rows=72902 loops=1)                                                                                                                                                  |
  Output: st.student_id                                                                                                                                                                                                                                    |
  Buffers: shared hit=34879380                                                                                                                                                                                                                             |
  ->  Hash Join  (cost=2043.88..5769.94 rows=2 width=20) (actual time=41.050..955.542 rows=90631 loops=1)                                                                                                                                                  |
        Output: t.student_id, snp.student_id                                                                                                                                                                                                               |
        Hash Cond: ((t.student_id = snp.student_id) AND (t.student_snapshot_date = snp.created_at))                                                                                                                                                        |
        Buffers: shared hit=3015                                                                                                                                                                                                                           |
        ->  Seq Scan on public."test" t  (cost=0.00..3046.31 rows=90631 width=18) (actual time=0.010..169.664 rows=90631 loops=1)                                                                                 |
              Output: t.id, t.student_id, t.student_snapshot_date|
              Buffers: shared hit=2140                                                                                                                                                                                                                     |
        ->  Hash  (cost=1342.55..1342.55 rows=46755 width=18) (actual time=39.342..39.343 rows=46755 loops=1)                                                                                                                                              |
              Output: snp.student_id, snp.created_at                                                                                                                                                                                                       |
              Buckets: 65536  Batches: 1  Memory Usage: 3069kB                                                                                                                                                                                             |
              Buffers: shared hit=875                                                                                                                                                                                                                      |
              ->  Seq Scan on public."student_snapshot" snp  (cost=0.00..1342.55 rows=46755 width=18) (actual time=0.018..13.942 rows=46755 loops=1)                                                                |
                    Output: snp.student_id, snp.created_at                                                                                                                                                                                                 |
                    Buffers: shared hit=875                                                                                                                                                                                                                |
  ->  Index Only Scan using "student_key" on public."student" st  (cost=0.41..331.08 rows=1 width=10) (actual time=12.086..21.000 rows=1 loops=90631)           |
        Output: st.program_id, st.organization_id, st.student_id                                                                                                                                                                                           |
        Index Cond: (st.student_id = t.student_id)                                                                                                                                                                                                         |
        Heap Fetches: 74061                                                                                                                                                                                                                                |
        Buffers: shared hit=34876365                                                                                                                                                                                                                       |
Planning:                                                                                                                                                                                                                                                  |
  Buffers: shared hit=40                                                                                                                                                                                                                                   |
Planning Time: 1.063 ms                                                                                                                                                                                                                                    |
Execution Time: 1904722.476 ms                                                                                                                                                                                                                             |
QUERY PLAN                                                                                                                                                                                                                                           |
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
Hash Join  (cost=4254.08..8568.10 rows=92784 width=10) (actual time=114.921..219.856 rows=74332 loops=1)                                                                                                                                             |
  Output: st.student_id                                                                                                                                                                                                                              |
  Hash Cond: (t.student_id = st.student_id)                                                                                                                                                                                                          |
  Buffers: shared hit=3744                                                                                                                                                                                                                           |
  ->  Seq Scan on public."test" t  (cost=0.00..3046.31 rows=90631 width=10) (actual time=0.010..12.670 rows=90631 loops=1)                                                                                  |
        Output: t.id, t.student_id, t.student_snapshot_date|
        Buffers: shared hit=2140                                                                                                                                                                                                                     |
  ->  Hash  (cost=3689.98..3689.98 rows=45128 width=20) (actual time=114.737..114.739 rows=36995 loops=1)                                                                                                                                            |
        Output: st.student_id, snp.student_id                                                                                                                                                                                                        |
        Buckets: 65536  Batches: 1  Memory Usage: 2391kB                                                                                                                                                                                             |
        Buffers: shared hit=1604                                                                                                                                                                                                                     |
        ->  Hash Join  (cost=1720.82..3689.98 rows=45128 width=20) (actual time=33.975..95.906 rows=36995 loops=1)                                                                                                                                   |
              Output: st.student_id, snp.student_id                                                                                                                                                                                                  |
              Hash Cond: (snp.student_id = st.student_id)                                                                                                                                                                                            |
              Buffers: shared hit=1604                                                                                                                                                                                                               |
              ->  Seq Scan on public."student_snapshot" snp  (cost=0.00..1342.55 rows=46755 width=10) (actual time=0.030..13.741 rows=46755 loops=1)                                                          |
                    Output: snp.student_id, snp.created_at, snp.program_id, snp.organization_id, snp.first_name, snp.last_name, snp.gender_id, snp.grade_id, snp.date_of_birth, snp.race, snp.academic, snp.zip, snp.state_id                        |
                    Buffers: shared hit=875                                                                                                                                                                                                          |
              ->  Hash  (cost=1169.81..1169.81 rows=44081 width=10) (actual time=31.513..31.514 rows=43262 loops=1)                                                                                                                                  |
                    Output: st.student_id                                                                                                                                                                                                            |
                    Buckets: 65536  Batches: 1  Memory Usage: 2287kB                                                                                                                                                                                 |
                    Buffers: shared hit=729                                                                                                                                                                                                          |
                    ->  Seq Scan on public."student" st  (cost=0.00..1169.81 rows=44081 width=10) (actual time=0.015..10.926 rows=43262 loops=1)                                                              |
                          Output: st.student_id                                                                                                                                                                                                      |
                          Buffers: shared hit=729                                                                                                                                                                                                    |
Planning:                                                                                                                                                                                                                                            |
  Buffers: shared hit=40                                                                                                                                                                                                                             |
Planning Time: 1.042 ms                                                                                                                                                                                                                              |
Execution Time: 223.517 ms                                                                                                                                                                                                                           |
CREATE STATISTICS "test_st_snp_pk" ON student_id, student_snapshot_date FROM "test";
CREATE STATISTICS "st_snp_pk" ON student_id, created_at FROM "student_snapshot";
alter table "test" alter student_id set statistics 500;
alter table "test" alter student_snapshot_date set statistics 500;
alter table "student_snapshot" alter student_id set statistics 500;
alter table "student_snapshot" alter created_at set statistics 500;

I tried clustering on a parallel indexes for test and student_snapshot to see if it would find more hits if they were sorted the same:

cluster "test" using "test_student_id_student_snapshot_date_idx";
cluster "student_snapshot" using "student_snapshot_pkey";
with test_w_snap as materialized (
  select t.*, snp.grade_id
  from test t
  join student_snapshot snp
    on snp.student_id = t.student_id
    and snp.created_at = t.student_snapshot_date
)
select t.*, st.grade_id as current_grade_id, t.grade_id as snapshot_grade_id
from student st
join test_w_snap t
  on t.student_id = st.student_id
added 115 characters in body
Source Link

The only thing I have done that has worked is to materialize part of the query but that isn't as efficient as it should be. But even that failed when I started adding back in the peripheral tables that were part of the more complex query.

The only thing I have done that has worked is to materialize part of the query but that isn't as efficient as it should be.

The only thing I have done that has worked is to materialize part of the query but that isn't as efficient as it should be. But even that failed when I started adding back in the peripheral tables that were part of the more complex query.

Source Link
Loading