Skip to content

Conversation

@pmattmann
Copy link
Member

@pmattmann pmattmann commented Mar 18, 2025

before:
SQL:

SELECT
  d0_.id AS id_0,
  d0_.createTime AS createtime_1,
  d0_.updateTime AS updatetime_2,
  d0_.dayOffset AS dayoffset_3,
  p1_.id AS id_4,
  p1_.createTime AS createtime_5,
  p1_.updateTime AS updatetime_6,
  p1_.description AS description_7,
  p1_.start AS start_8,
  p1_."end" AS end_9,
  d0_.periodId AS periodid_10,
  p1_.campId AS campid_11
FROM
  day d0_
  INNER JOIN period p1_ ON d0_.periodId = p1_.id
WHERE
  d0_.periodId IN (
    SELECT
      p2_.id
    FROM
      period p2_
      INNER JOIN view_user_camps v3_ ON (p2_.campId = v3_.campId)
    WHERE
      v3_.userId = ?
  )
ORDER BY
  d0_.createTime DESC,
  p1_.start ASC,
  d0_.dayOffset ASC

ExplainPlan:

Sort  (cost=94.93..95.35 rows=167 width=276)
  Sort Key: d0_.createtime DESC, p1_.start, d0_.dayoffset
  ->  Hash Join  (cost=69.53..88.77 rows=167 width=276)
        Hash Cond: ((d0_.periodid)::text = (p1_.id)::text)
        ->  Hash Semi Join  (cost=49.62..68.43 rows=167 width=170)
              Hash Cond: ((d0_.periodid)::text = (p2_.id)::text)
              ->  Seq Scan on day d0_  (cost=0.00..15.50 rows=550 width=120)
              ->  Hash  (cost=47.95..47.95 rows=134 width=50)
                    ->  Hash Join  (cost=30.56..47.95 rows=134 width=50)
                          Hash Cond: ((p2_.campid)::text = (v3_.campid)::text)
                          ->  Seq Scan on period p2_  (cost=0.00..14.40 rows=440 width=100)
                          ->  Hash  (cost=29.80..29.80 rows=61 width=50)
                                ->  Subquery Scan on v3_  (cost=0.14..29.80 rows=61 width=50)
                                      ->  Append  (cost=0.14..29.19 rows=61 width=132)
                                            ->  Nested Loop  (cost=0.14..20.11 rows=60 width=132)
                                                  ->  Index Only Scan using user_pkey on "user" u  (cost=0.14..8.16 rows=1 width=50)
                                                        Index Cond: (id = '9145944210a7'::text)
                                                  ->  Seq Scan on camp c  (cost=0.00..11.20 rows=60 width=50)
                                                        Filter: isprototype
                                            ->  Subquery Scan on "*SELECT* 2"  (cost=0.14..8.17 rows=1 width=132)
                                                  ->  Index Scan using idx_c93898a7b00651c on camp_collaboration cc  (cost=0.14..8.16 rows=1 width=150)
                                                        Index Cond: ((status)::text = 'established'::text)
                                                        Filter: ((userid)::text = '9145944210a7'::text)
        ->  Hash  (cost=14.40..14.40 rows=440 width=156)
              ->  Seq Scan on period p1_  (cost=0.00..14.40 rows=440 width=156)

after:
SQL:

SELECT
  d0_.id AS id_0,
  d0_.createTime AS createtime_1,
  d0_.updateTime AS updatetime_2,
  d0_.dayOffset AS dayoffset_3,
  p1_.id AS id_4,
  p1_.createTime AS createtime_5,
  p1_.updateTime AS updatetime_6,
  p1_.description AS description_7,
  p1_.start AS start_8,
  p1_."end" AS end_9,
  d0_.periodId AS periodid_10,
  p1_.campId AS campid_11
FROM
  day d0_
  INNER JOIN period p1_ ON d0_.periodId = p1_.id
WHERE
  p1_.campId IN (
    SELECT
      v2_.campId AS sclr_12
    FROM
      view_user_camps v2_
    WHERE
      v2_.userId = ?
  )
ORDER BY
  d0_.createTime DESC,
  p1_.start ASC,
  d0_.dayOffset ASC

ExplainPlan:

Sort  (cost=74.73..75.15 rows=168 width=276)
  Sort Key: d0_.createtime DESC, p1_.start, d0_.dayoffset
  ->  Hash Join  (cost=49.28..68.52 rows=168 width=276)
        Hash Cond: ((d0_.periodid)::text = (p1_.id)::text)
        ->  Seq Scan on day d0_  (cost=0.00..15.50 rows=550 width=120)
        ->  Hash  (cost=47.61..47.61 rows=134 width=156)
              ->  Hash Semi Join  (cost=30.56..47.61 rows=134 width=156)
                    Hash Cond: ((p1_.campid)::text = (v2_.campid)::text)
                    ->  Seq Scan on period p1_  (cost=0.00..14.40 rows=440 width=156)
                    ->  Hash  (cost=29.80..29.80 rows=61 width=50)
                          ->  Subquery Scan on v2_  (cost=0.14..29.80 rows=61 width=50)
                                ->  Append  (cost=0.14..29.19 rows=61 width=132)
                                      ->  Nested Loop  (cost=0.14..20.11 rows=60 width=132)
                                            ->  Index Only Scan using user_pkey on "user" u  (cost=0.14..8.16 rows=1 width=50)
                                                  Index Cond: (id = '9145944210a7'::text)
                                            ->  Seq Scan on camp c  (cost=0.00..11.20 rows=60 width=50)
                                                  Filter: isprototype
                                      ->  Subquery Scan on "*SELECT* 2"  (cost=0.14..8.17 rows=1 width=132)
                                            ->  Index Scan using idx_c93898a7b00651c on camp_collaboration cc  (cost=0.14..8.16 rows=1 width=150)
                                                  Index Cond: ((status)::text = 'established'::text)
                                                  Filter: ((userid)::text = '9145944210a7'::text)

Prevents from joining the same table twice
@manuelmeister manuelmeister added the deploy! Creates a feature branch deployment for this PR label Mar 18, 2025
@pmattmann pmattmann requested a review from a team March 18, 2025 21:45
@github-actions
Copy link

github-actions bot commented Mar 18, 2025

Feature branch deployment currently inactive.

If the PR is still open, you can add the deploy! label to this PR to trigger a feature branch deployment.

Copy link
Contributor

@BacLuc BacLuc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks very good to me.
some tests would be nice.

@pmattmann pmattmann requested a review from a team March 23, 2025 20:36
@pmattmann
Copy link
Member Author

pmattmann commented Mar 23, 2025

some tests would be nice.

I have just added some tests.

@pmattmann pmattmann changed the title Perf: Reuse existing joins in QueryBuilder Performance: Reuse existing joins in QueryBuilder Mar 26, 2025
@pmattmann pmattmann added this pull request to the merge queue Apr 11, 2025
Merged via the queue into ecamp:devel with commit 960af52 Apr 11, 2025
40 checks passed
@pmattmann pmattmann deleted the feature/perf branch April 11, 2025 21:43
@carlobeltrame carlobeltrame mentioned this pull request Jun 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

deploy! Creates a feature branch deployment for this PR Performance

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants