Skip to content

Instantly share code, notes, and snippets.

@jer-k
Last active August 17, 2025 02:46
Show Gist options
  • Select an option

  • Save jer-k/b6722690c518b968e7fd0b6bdcd65732 to your computer and use it in GitHub Desktop.

Select an option

Save jer-k/b6722690c518b968e7fd0b6bdcd65732 to your computer and use it in GitHub Desktop.
Zero/Sqlite vs AR/Postgres

Comparing a query in Zero/Sqlite to ActiveRecord/Postgres

Noticing a huge slowdown in a query with a ton of related tables in Zero.

The query is

  return z.query.scenarios
    .where("teamId", team.id)
    .related("team", (q_team) => q_team.one())
    .related("client", (q_client) => q_client.one())
    .related("lender", (q_lender) => q_lender.one())
    .related("loanPurpose", (q_loan_purpose) => q_loan_purpose.one())
    .related("loanType", (q_loan_type) => q_loan_type.one())
    .related("propertyType", (q_property_type) => q_property_type.one());

Analyzing Zero Query

./node_modules/.bin/dotenvx run -f .env.local -- npx analyze-query --schema-path='./lib/zero/schema.ts' --query='scenarios.where("teamId", 1).related("team", (q_team) => q_team.one()).related("client", (q_client) => q_client.one()).related("lender", (q_lender) => q_lender.one()).related("loanPurpose", (q_loan_purpose) => q_loan_purpose.one()).related("loanType", (q_loan_type) => q_loan_type.one()).related("propertyType", (q_property_type) => q_property_type.one())' --apply-permissions --auth-data='{"sub":"1", "lender_id": 1, "team_ids": [1]}'

The results show this query is taking 1124.76ms

=== Query After Permissions: ===

scenarios
  .where("team_id", 1)
  .where("team_id", "IN", [1])
  .related("team", (q) =>
    q.where("1", "IS NOT", null).orderBy("id", "asc").limit(1),
  )
  .related("client", (q) =>
    q.where("1", "IS NOT", null).orderBy("id", "asc").limit(1),
  )
  .related("lender", (q) =>
    q.where("1", "IS NOT", null).orderBy("id", "asc").limit(1),
  )
  .related("loanPurpose", (q) =>
    q.where("1", "IS NOT", null).orderBy("id", "asc").limit(1),
  )
  .related("loanType", (q) =>
    q.where("1", "IS NOT", null).orderBy("id", "asc").limit(1),
  )
  .related("propertyType", (q) =>
    q.where("1", "IS NOT", null).orderBy("id", "asc").limit(1),
  )
  .orderBy("id", "asc")

=== Query Stats: ===

scenarios vended: { 'SELECT "id","public_id","down_payment_percentage","interest_rate","name","purchase_price","refinance","term","created_at","client_id","lender_id","loan_purpose_id","loan_type_id","property_type_id","team_id" FROM "scenarios" WHERE ("team_id" = ? AND "team_id" IN (SELECT value FROM json_each(?))) ORDER BY "id" asc': 2040 }

teams vended: { 'SELECT "id","public_id","name","avatar_url","organization_id" FROM "teams" WHERE "id" IS ? AND ? IS NOT ? ORDER BY "id" asc': 2040 }

clients vended: { 'SELECT "id","public_id","avatar_url","created_at","email_address","first_name","last_name","full_name","phone_number","team_id","user_id" FROM "clients" WHERE "id" IS ? AND ? IS NOT ? ORDER BY "id" asc': 2040 }

lenders vended: { 'SELECT "id","user_id" FROM "lenders" WHERE "id" IS ? AND ? IS NOT ? ORDER BY "id" asc': 2040 }

loan_purposes vended: { 'SELECT "id","name" FROM "loan_purposes" WHERE "id" IS ? AND ? IS NOT ? ORDER BY "id" asc': 2040 }

loan_types vended: { 'SELECT "id","name" FROM "loan_types" WHERE "id" IS ? AND ? IS NOT ? ORDER BY "id" asc': 2040 }

property_types vended: { 'SELECT "id","name" FROM "property_types" WHERE "id" IS ? AND ? IS NOT ? ORDER BY "id" asc': 2040 }

total rows considered: 14280 time: 1124.76ms ms

=== Query Plans: ===

query SELECT "id","public_id","down_payment_percentage","interest_rate","name","purchase_price","refinance","term","created_at","client_id","lender_id","loan_purpose_id","loan_type_id","property_type_id","team_id" FROM "scenarios" WHERE ("team_id" = ? AND "team_id" IN (SELECT value FROM json_each(?))) ORDER BY "id" asc                                                                                 
SEARCH scenarios USING INDEX index_scenarios_on_team_id (team_id=?)                           
LIST SUBQUERY 1
SCAN json_each VIRTUAL TABLE INDEX 1:
CREATE BLOOM FILTER
USE TEMP B-TREE FOR ORDER BY
query SELECT "id","public_id","name","avatar_url","organization_id" FROM "teams" WHERE "id" IS ? AND ? IS NOT ? ORDER BY "id" asc
SEARCH teams USING INDEX teams_pkey (id=?)
query SELECT "id","public_id","avatar_url","created_at","email_address","first_name","last_name","full_name","phone_number","team_id","user_id" FROM "clients" WHERE "id" IS ? AND ? IS NOT ? 
ORDER BY "id" asc 
SEARCH clients 
USING INDEX clients_pkey (id=?)
query SELECT "id","user_id" FROM "lenders" WHERE "id" IS ? AND ? IS NOT ? ORDER BY "id" asc
SEARCH lenders USING INDEX lenders_pkey (id=?)
query SELECT "id","name" FROM "loan_purposes" WHERE "id" IS ? AND ? IS NOT ? ORDER BY "id" asc
SEARCH loan_purposes USING INDEX loan_purposes_pkey (id=?)
query SELECT "id","name" FROM "loan_types" WHERE "id" IS ? AND ? IS NOT ? ORDER BY "id" asc
SEARCH loan_types USING INDEX loan_types_pkey (id=?)
query SELECT "id","name" FROM "property_types" WHERE "id" IS ? AND ? IS NOT ? ORDER BY "id" asc
SEARCH property_types USING INDEX property_types_pkey (id=?)

Analyzing Postgres Query

In ActiveRecord we can do Scenario.where(team_id: 1).preload(:loan_type, :loan_purpose, :property_type, :lender, :client, :team).explain. Using preload tells ActiveRecord to issue separate queries to all the associated tables to gather the data, rather than attempting to create a bunch of joins/subqueries.

The results summed up are about 125ms

  Scenario Load (114.9ms)  SELECT "scenarios".* FROM "scenarios" WHERE "scenarios"."team_id" = 1 /*application='LendingSheetsBackend'*/
  LoanType Load (0.6ms)  SELECT "loan_types".* FROM "loan_types" WHERE "loan_types"."id" IN (1, 2, 3, 4, 5, 6, 7, 8, 9) /*application='LendingSheetsBackend'*/
  LoanPurpose Load (0.4ms)  SELECT "loan_purposes".* FROM "loan_purposes" WHERE "loan_purposes"."id" IN (1, 2, 3, 4, 5, 6) /*application='LendingSheetsBackend'*/
  PropertyType Load (0.5ms)  SELECT "property_types".* FROM "property_types" WHERE "property_types"."id" IN (1, 2, 3, 4, 5, 6, 7) /*application='LendingSheetsBackend'*/
  Lender Load (0.5ms)  SELECT "lenders".* FROM "lenders" WHERE "lenders"."id" IN (1, 3) /*application='LendingSheetsBackend'*/
  Client Load (7.3ms)  SELECT "clients".* FROM "clients" WHERE "clients"."id" IN (7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108) /*application='LendingSheetsBackend'*/
  Team Load (0.4ms)  SELECT "teams".* FROM "teams" WHERE "teams"."id" = 1 /*application='LendingSheetsBackend'*/

And all the query plans

EXPLAIN SELECT "scenarios".* FROM "scenarios" WHERE "scenarios"."team_id" = 1 /*application='LendingSheetsBackend'*/
                                            QUERY PLAN
---------------------------------------------------------------------------------------------------
 Index Scan using index_scenarios_on_team_id on scenarios  (cost=0.28..100.94 rows=2038 width=137)
   Index Cond: (team_id = 1)
(2 rows)
EXPLAIN SELECT "loan_types".* FROM "loan_types" WHERE "loan_types"."id" IN (1, 2, 3, 4, 5, 6, 7, 8, 9) /*application='LendingSheetsBackend'*/
                        QUERY PLAN
-----------------------------------------------------------
 Seq Scan on loan_types  (cost=0.02..1.16 rows=6 width=88)
   Filter: (id = ANY ('{1,2,3,4,5,6,7,8,9}'::bigint[]))
(2 rows)
EXPLAIN SELECT "loan_purposes".* FROM "loan_purposes" WHERE "loan_purposes"."id" IN (1, 2, 3, 4, 5, 6) /*application='LendingSheetsBackend'*/
                          QUERY PLAN
--------------------------------------------------------------
 Seq Scan on loan_purposes  (cost=0.00..1.10 rows=6 width=56)
   Filter: (id = ANY ('{1,2,3,4,5,6}'::bigint[]))
(2 rows)
EXPLAIN SELECT "property_types".* FROM "property_types" WHERE "property_types"."id" IN (1, 2, 3, 4, 5, 6, 7) /*application='LendingSheetsBackend'*/
                          QUERY PLAN
---------------------------------------------------------------
 Seq Scan on property_types  (cost=0.00..1.13 rows=7 width=56)
   Filter: (id = ANY ('{1,2,3,4,5,6,7}'::bigint[]))
(2 rows)
EXPLAIN SELECT "lenders".* FROM "lenders" WHERE "lenders"."id" IN (1, 3) /*application='LendingSheetsBackend'*/                                                                  QUERY PLAN
--------------------------------------------------------
 Seq Scan on lenders  (cost=0.00..1.04 rows=2 width=32)
   Filter: (id = ANY ('{1,3}'::bigint[]))
(2 rows)
 EXPLAIN SELECT "clients".* FROM "clients" WHERE "clients"."id" IN (7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108) /*application='LendingSheetsBackend'*/
 
 Seq Scan on clients  (cost=0.26..4.88 rows=102 width=182)
 Filter: (id = ANY ('{7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108}'::bigint[]))
 (2 rows)
EXPLAIN SELECT "scenarios".* FROM "scenarios" WHERE "scenarios"."team_id" = 1 /*application='LendingSheetsBackend'*/
                                           QUERY PLAN
---------------------------------------------------------------------------------------------------
Index Scan using index_scenarios_on_team_id on scenarios  (cost=0.28..100.94 rows=2038 width=137)
  Index Cond: (team_id = 1)
(2 rows)
EXPLAIN SELECT "loan_types".* FROM "loan_types" WHERE "loan_types"."id" IN (1, 2, 3, 4, 5, 6, 7, 8, 9) /*application='LendingSheetsBackend'*/
                        QUERY PLAN
-----------------------------------------------------------
 Seq Scan on loan_types  (cost=0.02..1.16 rows=6 width=88)
   Filter: (id = ANY ('{1,2,3,4,5,6,7,8,9}'::bigint[]))
(2 rows)
EXPLAIN SELECT "loan_purposes".* FROM "loan_purposes" WHERE "loan_purposes"."id" IN (1, 2, 3, 4, 5, 6) /*application='LendingSheetsBackend'*/
                          QUERY PLAN
--------------------------------------------------------------
 Seq Scan on loan_purposes  (cost=0.00..1.10 rows=6 width=56)
   Filter: (id = ANY ('{1,2,3,4,5,6}'::bigint[]))
(2 rows)
EXPLAIN SELECT "property_types".* FROM "property_types" WHERE "property_types"."id" IN (1, 2, 3, 4, 5, 6, 7) /*application='LendingSheetsBackend'*/
                          QUERY PLAN
---------------------------------------------------------------
 Seq Scan on property_types  (cost=0.00..1.13 rows=7 width=56)
   Filter: (id = ANY ('{1,2,3,4,5,6,7}'::bigint[]))
(2 rows)
EXPLAIN SELECT "lenders".* FROM "lenders" WHERE "lenders"."id" IN (1, 3) /*application='LendingSheetsBackend'*/
                       QUERY PLAN
--------------------------------------------------------
 Seq Scan on lenders  (cost=0.00..1.04 rows=2 width=32)
   Filter: (id = ANY ('{1,3}'::bigint[]))
(2 rows)
EXPLAIN SELECT "teams".* FROM "teams" WHERE "teams"."id" = 1 /*application='LendingSheetsBackend'*/
                      QUERY PLAN
-------------------------------------------------------
 Seq Scan on teams  (cost=0.00..1.02 rows=1 width=138)
   Filter: (id = 1)
(2 rows)
@jer-k
Copy link
Author

jer-k commented Aug 17, 2025

Scenario.where(team_id: 1).eager_load(:loan_type, :loan_purpose, :property_type, :lender, :client, :team).explain
SQL (235.2ms) SELECT "scenarios"."id" AS t0_r0, "scenarios"."team_id" AS t0_r1, "scenarios"."client_id" AS t0_r2, "scenarios"."lender_id" AS t0_r3, "scenarios"."loan_type_id" AS t0_r4, "scenarios"."property_type_id" AS t0_r5, "scenarios"."loan_purpose_id" AS t0_r6, "scenarios"."name" AS t0_r7, "scenarios"."purchase_price" AS t0_r8, "scenarios"."down_payment_percentage" AS t0_r9, "scenarios"."interest_rate" AS t0_r10, "scenarios"."term" AS t0_r11, "scenarios"."refinance" AS t0_r12, "scenarios"."public_id" AS t0_r13, "scenarios"."created_at" AS t0_r14, "scenarios"."updated_at" AS t0_r15, "loan_types"."id" AS t1_r0, "loan_types"."name" AS t1_r1, "loan_types"."short_name" AS t1_r2, "loan_types"."created_at" AS t1_r3, "loan_types"."updated_at" AS t1_r4, "loan_purposes"."id" AS t2_r0, "loan_purposes"."name" AS t2_r1, "loan_purposes"."created_at" AS t2_r2, "loan_purposes"."updated_at" AS t2_r3, "property_types"."id" AS t3_r0, "property_types"."name" AS t3_r1, "property_types"."created_at" AS t3_r2, "property_types"."updated_at" AS t3_r3, "lenders"."id" AS t4_r0, "lenders"."user_id" AS t4_r1, "lenders"."created_at" AS t4_r2, "lenders"."updated_at" AS t4_r3, "clients"."id" AS t5_r0, "clients"."user_id" AS t5_r1, "clients"."team_id" AS t5_r2, "clients"."first_name" AS t5_r3, "clients"."last_name" AS t5_r4, "clients"."email_address" AS t5_r5, "clients"."avatar_url" AS t5_r6, "clients"."created_at" AS t5_r7, "clients"."updated_at" AS t5_r8, "clients"."phone_number" AS t5_r9, "clients"."public_id" AS t5_r10, "clients"."full_name" AS t5_r11, "teams"."id" AS t6_r0, "teams"."name" AS t6_r1, "teams"."avatar_url" AS t6_r2, "teams"."organization_id" AS t6_r3, "teams"."created_at" AS t6_r4, "teams"."updated_at" AS t6_r5, "teams"."public_id" AS t6_r6 FROM "scenarios" LEFT OUTER JOIN "loan_types" ON "loan_types"."id" = "scenarios"."loan_type_id" LEFT OUTER JOIN "loan_purposes" ON "loan_purposes"."id" = "scenarios"."loan_purpose_id" LEFT OUTER JOIN "property_types" ON "property_types"."id" = "scenarios"."property_type_id" LEFT OUTER JOIN "lenders" ON "lenders"."id" = "scenarios"."lender_id" LEFT OUTER JOIN "clients" ON "clients"."id" = "scenarios"."client_id" LEFT OUTER JOIN "teams" ON "teams"."id" = "scenarios"."team_id" WHERE "scenarios"."team_id" = 1 /application='LendingSheetsBackend'/ => EXPLAIN SELECT "scenarios"."id" AS t0_r0, "scenarios"."team_id" AS t0_r1, "scenarios"."client_id" AS t0_r2, "scenarios"."lender_id" AS t0_r3, "scenarios"."loan_type_id" AS t0_r4, "scenarios"."property_type_id" AS t0_r5, "scenarios"."loan_purpose_id" AS t0_r6, "scenarios"."name" AS t0_r7, "scenarios"."purchase_price" AS t0_r8, "scenarios"."down_payment_percentage" AS t0_r9, "scenarios"."interest_rate" AS t0_r10, "scenarios"."term" AS t0_r11, "scenarios"."refinance" AS t0_r12, "scenarios"."public_id" AS t0_r13, "scenarios"."created_at" AS t0_r14, "scenarios"."updated_at" AS t0_r15, "loan_types"."id" AS t1_r0, "loan_types"."name" AS t1_r1, "loan_types"."short_name" AS t1_r2, "loan_types"."created_at" AS t1_r3, "loan_types"."updated_at" AS t1_r4, "loan_purposes"."id" AS t2_r0, "loan_purposes"."name" AS t2_r1, "loan_purposes"."created_at" AS t2_r2, "loan_purposes"."updated_at" AS t2_r3, "property_types"."id" AS t3_r0, "property_types"."name" AS t3_r1, "property_types"."created_at" AS t3_r2, "property_types"."updated_at" AS t3_r3, "lenders"."id" AS t4_r0, "lenders"."user_id" AS t4_r1, "lenders"."created_at" AS t4_r2, "lenders"."updated_at" AS t4_r3, "clients"."id" AS t5_r0, "clients"."user_id" AS t5_r1, "clients"."team_id" AS t5_r2, "clients"."first_name" AS t5_r3, "clients"."last_name" AS t5_r4, "clients"."email_address" AS t5_r5, "clients"."avatar_url" AS t5_r6, "clients"."created_at" AS t5_r7, "clients"."updated_at" AS t5_r8, "clients"."phone_number" AS t5_r9, "clients"."public_id" AS t5_r10, "clients"."full_name" AS t5_r11, "teams"."id" AS t6_r0, "teams"."name" AS t6_r1, "teams"."avatar_url" AS t6_r2, "teams"."organization_id" AS t6_r3, "teams"."created_at" AS t6_r4, "teams"."updated_at" AS t6_r5, "teams"."public_id" AS t6_r6 FROM "scenarios" LEFT OUTER JOIN "loan_types" ON "loan_types"."id" = "scenarios"."loan_type_id" LEFT OUTER JOIN "loan_purposes" ON "loan_purposes"."id" = "scenarios"."loan_purpose_id" LEFT OUTER JOIN "property_types" ON "property_types"."id" = "scenarios"."property_type_id" LEFT OUTER JOIN "lenders" ON "lenders"."id" = "scenarios"."lender_id" LEFT OUTER JOIN "clients" ON "clients"."id" = "scenarios"."client_id" LEFT OUTER JOIN "teams" ON "teams"."id" = "scenarios"."team_id" WHERE "scenarios"."team_id" = 1 /application='LendingSheetsBackend'/ QUERY PLAN --------------------------------------------------------------------------------------------------------------------------------------- Nested Loop Left Join (cost=10.27..181.49 rows=2038 width=689) -> Hash Left Join (cost=10.27..154.99 rows=2038 width=551) Hash Cond: (scenarios.client_id = clients.id) -> Hash Left Join (cost=4.84..143.99 rows=2038 width=369) Hash Cond: (scenarios.lender_id = lenders.id) -> Hash Left Join (cost=3.78..130.02 rows=2038 width=337) Hash Cond: (scenarios.property_type_id = property_types.id) -> Hash Left Join (cost=2.62..120.28 rows=2038 width=281)
Hash Cond: (scenarios.loan_purpose_id = loan_purposes.id)
-> Hash Left Join (cost=1.48..110.01 rows=2038 width=225)
Hash Cond: (scenarios.loan_type_id = loan_types.id) -> Index Scan using index_scenarios_on_team_id on scenarios (cost=0.28..100.94 rows=2038 width=137)
Index Cond: (team_id = 1)
-> Hash (cost=1.09..1.09 rows=9 width=88)
-> Seq Scan on loan_types (cost=0.00..1.09 rows=9 width=88)
-> Hash (cost=1.06..1.06 rows=6 width=56)
-> Seq Scan on loan_purposes (cost=0.00..1.06 rows=6 width=56)
-> Hash (cost=1.07..1.07 rows=7 width=56) -> Seq Scan on property_types (cost=0.00..1.07 rows=7 width=56)
-> Hash (cost=1.03..1.03 rows=3 width=32)
-> Seq Scan on lenders (cost=0.00..1.03 rows=3 width=32)
-> Hash (cost=4.08..4.08 rows=108 width=182)
Preparing full inspection value...
=>
EXPLAIN SELECT "scenarios"."id" AS t0_r0, "scenarios"."team_id" AS t0_r1, "scenarios"."client_id" AS t0_r2, "scenarios"."lender_id" AS t0_r3, "scenarios"."loan_type_id" AS t0_r4, "scenarios"."property_type_id" AS t0_r5, "scenarios"."loan_purpose_id" AS t0_r6, "scenarios"."name" AS t0_r7, "scenarios"."purchase_price" AS t0_r8, "scenarios"."down_payment_percentage" AS t0_r9, "scenarios"."interest_rate" AS t0_r10, "scenarios"."term" AS t0_r11, "scenarios"."refinance" AS t0_r12, "scenarios"."public_id" AS t0_r13, "scenarios"."created_at" AS t0_r14, "scenarios"."updated_at" AS t0_r15, "loan_types"."id" AS t1_r0, "loan_types"."name" AS t1_r1, "loan_types"."short_name" AS t1_r2, "loan_types"."created_at" AS t1_r3, "loan_types"."updated_at" AS t1_r4, "loan_purposes"."id" AS t2_r0, "loan_purposes"."name" AS t2_r1, "loan_purposes"."created_at" AS t2_r2, "loan_purposes"."updated_at" AS t2_r3, "property_types"."id" AS t3_r0, "property_types"."name" AS t3_r1, "property_types"."created_at" AS t3_r2, "property_types"."updated_at" AS t3_r3, "lenders"."id" AS t4_r0, "lenders"."user_id" AS t4_r1, "lenders"."created_at" AS t4_r2, "lenders"."updated_at" AS t4_r3, "clients"."id" AS t5_r0, "clients"."user_id" AS t5_r1, "clients"."team_id" AS t5_r2, "clients"."first_name" AS t5_r3, "clients"."last_name" AS t5_r4, "clients"."email_address" AS t5_r5, "clients"."avatar_url" AS t5_r6, "clients"."created_at" AS t5_r7, "clients"."updated_at" AS t5_r8, "clients"."phone_number" AS t5_r9, "clients"."public_id" AS t5_r10, "clients"."full_name" AS t5_r11, "teams"."id" AS t6_r0, "teams"."name" AS t6_r1, "teams"."avatar_url" AS t6_r2, "teams"."organization_id" AS t6_r3, "teams"."created_at" AS t6_r4, "teams"."updated_at" AS t6_r5, "teams"."public_id" AS t6_r6 FROM "scenarios" LEFT OUTER JOIN "loan_types" ON "loan_types"."id" = "scenarios"."loan_type_id" LEFT OUTER JOIN "loan_purposes" ON "loan_purposes"."id" = "scenarios"."loan_purpose_id" LEFT OUTER JOIN "property_types" ON "property_types"."id" = "scenarios"."property_type_id" LEFT OUTER JOIN "lenders" ON "lenders"."id" = "scenarios"."lender_id" LEFT OUTER JOIN "clients" ON "clients"."id" = "scenarios"."client_id" LEFT OUTER JOIN "teams" ON "teams"."id" = "scenarios"."team_id" WHERE "scenarios"."team_id" = 1 /application='LendingSheetsBackend'/ QUERY PLAN

Nested Loop Left Join (cost=10.27..181.49 rows=2038 width=689)
-> Hash Left Join (cost=10.27..154.99 rows=2038 width=551)
Hash Cond: (scenarios.client_id = clients.id)
-> Hash Left Join (cost=4.84..143.99 rows=2038 width=369)
Hash Cond: (scenarios.lender_id = lenders.id) -> Hash Left Join (cost=3.78..130.02 rows=2038 width=337)
Hash Cond: (scenarios.property_type_id = property_types.id)
-> Hash Left Join (cost=2.62..120.28 rows=2038 width=281)
Hash Cond: (scenarios.loan_purpose_id = loan_purposes.id)
-> Hash Left Join (cost=1.48..110.01 rows=2038 width=225)
Hash Cond: (scenarios.loan_type_id = loan_types.id)
-> Index Scan using index_scenarios_on_team_id on scenarios (cost=0.28..100.94 rows=2038 width=137) Index Cond: (team_id = 1)
-> Hash (cost=1.09..1.09 rows=9 width=88)
-> Seq Scan on loan_types (cost=0.00..1.09 rows=9 width=88)
-> Hash (cost=1.06..1.06 rows=6 width=56)
-> Seq Scan on loan_purposes (cost=0.00..1.06 rows=6 width=56)
-> Hash (cost=1.07..1.07 rows=7 width=56)
-> Seq Scan on property_types (cost=0.00..1.07 rows=7 width=56) -> Hash (cost=1.03..1.03 rows=3 width=32)
-> Seq Scan on lenders (cost=0.00..1.03 rows=3 width=32)
-> Hash (cost=4.08..4.08 rows=108 width=182)
-> Seq Scan on clients (cost=0.00..4.08 rows=108 width=182)
-> Materialize (cost=0.00..1.03 rows=1 width=138)
-> Seq Scan on teams (cost=0.00..1.02 rows=1 width=138)
Filter: (id = 1)
(26 rows)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment