-
-
Notifications
You must be signed in to change notification settings - Fork 3k
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
refactor(server): filter assets by people using a subquery instead of a cte #15768
base: main
Are you sure you want to change the base?
Conversation
My only concern is whether this would produce the same query plan as the CTE. Can you test the execution time of a query that uses this helper, both for the CTE and subquery versions? Ideally using |
Ok, will do that 👍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Make sure to run make sql
and commit those changes as well.
Edit: oh maybe we should generate a query that actually uses the people relation
I tried both explain and explain analyze and there's no difference in the output besides some slight differences in timing. Using CTE:Explain:[
{
"QUERY PLAN": "Limit (cost=19.06..32.83 rows=1 width=477)"
},
{
"QUERY PLAN": " -> Result (cost=19.06..32.83 rows=1 width=477)"
},
{
"QUERY PLAN": " -> Sort (cost=19.06..19.07 rows=1 width=445)"
},
{
"QUERY PLAN": " Sort Key: assets.\"fileCreatedAt\" DESC"
},
{
"QUERY PLAN": " -> Nested Loop (cost=8.90..19.05 rows=1 width=445)"
},
{
"QUERY PLAN": " Join Filter: (asset_faces.\"assetId\" = exif.\"assetId\")"
},
{
"QUERY PLAN": " -> Nested Loop (cost=8.75..18.71 rows=1 width=429)"
},
{
"QUERY PLAN": " -> GroupAggregate (cost=8.61..10.47 rows=1 width=16)"
},
{
"QUERY PLAN": " Group Key: asset_faces.\"assetId\""
},
{
"QUERY PLAN": " Filter: (count(DISTINCT asset_faces.\"personId\") = '2'::bigint)"
},
{
"QUERY PLAN": " -> Sort (cost=8.61..8.84 rows=94 width=32)"
},
{
"QUERY PLAN": " Sort Key: asset_faces.\"assetId\""
},
{
"QUERY PLAN": " -> Seq Scan on asset_faces (cost=0.00..5.53 rows=94 width=32)"
},
{
"QUERY PLAN": " Filter: (\"personId\" = ANY ('{fb80fce1-1e1d-4d5f-bdf1-316221ec8548,8b780879-189b-4dca-81a4-62c614680486}'::uuid[]))"
},
{
"QUERY PLAN": " -> Index Scan using \"PK_da96729a8b113377cfb6a62439c\" on assets (cost=0.15..8.17 rows=1 width=413)"
},
{
"QUERY PLAN": " Index Cond: (id = asset_faces.\"assetId\")"
},
{
"QUERY PLAN": " Filter: (\"isVisible\" AND (NOT \"isArchived\") AND (\"deletedAt\" IS NULL) AND (\"ownerId\" = ANY ('{fbf9fd06-5f1a-4924-9f7e-5e8625c62fa5}'::uuid[])))"
},
{
"QUERY PLAN": " -> Index Scan using \"PK_c0117fdbc50b917ef9067740c44\" on exif (cost=0.15..0.33 rows=1 width=434)"
},
{
"QUERY PLAN": " Index Cond: (\"assetId\" = assets.id)"
},
{
"QUERY PLAN": " SubPlan 1"
},
{
"QUERY PLAN": " -> Aggregate (cost=13.74..13.75 rows=1 width=32)"
},
{
"QUERY PLAN": " -> Nested Loop Left Join (cost=0.15..13.72 rows=1 width=273)"
},
{
"QUERY PLAN": " -> Seq Scan on asset_faces asset_faces_1 (cost=0.00..5.53 rows=1 width=116)"
},
{
"QUERY PLAN": " Filter: (\"assetId\" = assets.id)"
},
{
"QUERY PLAN": " -> Index Scan using \"PK_5fdaf670315c4b7e70cce85daa3\" on person (cost=0.15..8.17 rows=1 width=173)"
},
{
"QUERY PLAN": " Index Cond: (id = asset_faces_1.\"personId\")"
}
] Explain analyze: [
{
"QUERY PLAN": [
{
"Plan": {
"Node Type": "Limit",
"Parallel Aware": false,
"Async Capable": false,
"Startup Cost": 19.06,
"Total Cost": 32.83,
"Plan Rows": 1,
"Plan Width": 477,
"Actual Startup Time": 0.334,
"Actual Total Time": 0.336,
"Actual Rows": 1,
"Actual Loops": 1,
"Plans": [
{
"Node Type": "Result",
"Parent Relationship": "Outer",
"Parallel Aware": false,
"Async Capable": false,
"Startup Cost": 19.06,
"Total Cost": 32.83,
"Plan Rows": 1,
"Plan Width": 477,
"Actual Startup Time": 0.333,
"Actual Total Time": 0.335,
"Actual Rows": 1,
"Actual Loops": 1,
"Plans": [
{
"Node Type": "Sort",
"Parent Relationship": "Outer",
"Parallel Aware": false,
"Async Capable": false,
"Startup Cost": 19.06,
"Total Cost": 19.07,
"Plan Rows": 1,
"Plan Width": 445,
"Actual Startup Time": 0.188,
"Actual Total Time": 0.189,
"Actual Rows": 1,
"Actual Loops": 1,
"Sort Key": [
"assets.\"fileCreatedAt\" DESC"
],
"Sort Method": "quicksort",
"Sort Space Used": 27,
"Sort Space Type": "Memory",
"Plans": [
{
"Node Type": "Nested Loop",
"Parent Relationship": "Outer",
"Parallel Aware": false,
"Async Capable": false,
"Join Type": "Inner",
"Startup Cost": 8.9,
"Total Cost": 19.05,
"Plan Rows": 1,
"Plan Width": 445,
"Actual Startup Time": 0.155,
"Actual Total Time": 0.164,
"Actual Rows": 1,
"Actual Loops": 1,
"Inner Unique": true,
"Join Filter": "(asset_faces.\"assetId\" = exif.\"assetId\")",
"Rows Removed by Join Filter": 0,
"Plans": [
{
"Node Type": "Nested Loop",
"Parent Relationship": "Outer",
"Parallel Aware": false,
"Async Capable": false,
"Join Type": "Inner",
"Startup Cost": 8.75,
"Total Cost": 18.71,
"Plan Rows": 1,
"Plan Width": 429,
"Actual Startup Time": 0.117,
"Actual Total Time": 0.126,
"Actual Rows": 1,
"Actual Loops": 1,
"Inner Unique": true,
"Plans": [
{
"Node Type": "Aggregate",
"Strategy": "Sorted",
"Partial Mode": "Simple",
"Parent Relationship": "Outer",
"Parallel Aware": false,
"Async Capable": false,
"Startup Cost": 8.61,
"Total Cost": 10.47,
"Plan Rows": 1,
"Plan Width": 16,
"Actual Startup Time": 0.107,
"Actual Total Time": 0.115,
"Actual Rows": 1,
"Actual Loops": 1,
"Group Key": [
"asset_faces.\"assetId\""
],
"Filter": "(count(DISTINCT asset_faces.\"personId\") = '2'::bigint)",
"Rows Removed by Filter": 64,
"Plans": [
{
"Node Type": "Sort",
"Parent Relationship": "Outer",
"Parallel Aware": false,
"Async Capable": false,
"Startup Cost": 8.61,
"Total Cost": 8.84,
"Plan Rows": 94,
"Plan Width": 32,
"Actual Startup Time": 0.058,
"Actual Total Time": 0.061,
"Actual Rows": 69,
"Actual Loops": 1,
"Sort Key": [
"asset_faces.\"assetId\""
],
"Sort Method": "quicksort",
"Sort Space Used": 30,
"Sort Space Type": "Memory",
"Plans": [
{
"Node Type": "Seq Scan",
"Parent Relationship": "Outer",
"Parallel Aware": false,
"Async Capable": false,
"Relation Name": "asset_faces",
"Alias": "asset_faces",
"Startup Cost": 0,
"Total Cost": 5.53,
"Plan Rows": 94,
"Plan Width": 32,
"Actual Startup Time": 0.008,
"Actual Total Time": 0.021,
"Actual Rows": 69,
"Actual Loops": 1,
"Filter": "(\"personId\" = ANY ('{fb80fce1-1e1d-4d5f-bdf1-316221ec8548,8b780879-189b-4dca-81a4-62c614680486}'::uuid[]))",
"Rows Removed by Filter": 72
}
]
}
]
},
{
"Node Type": "Index Scan",
"Parent Relationship": "Inner",
"Parallel Aware": false,
"Async Capable": false,
"Scan Direction": "Forward",
"Index Name": "PK_da96729a8b113377cfb6a62439c",
"Relation Name": "assets",
"Alias": "assets",
"Startup Cost": 0.15,
"Total Cost": 8.17,
"Plan Rows": 1,
"Plan Width": 413,
"Actual Startup Time": 0.009,
"Actual Total Time": 0.009,
"Actual Rows": 1,
"Actual Loops": 1,
"Index Cond": "(id = asset_faces.\"assetId\")",
"Rows Removed by Index Recheck": 0,
"Filter": "(\"isVisible\" AND (NOT \"isArchived\") AND (\"deletedAt\" IS NULL) AND (\"ownerId\" = ANY ('{fbf9fd06-5f1a-4924-9f7e-5e8625c62fa5}'::uuid[])))",
"Rows Removed by Filter": 0
}
]
},
{
"Node Type": "Index Scan",
"Parent Relationship": "Inner",
"Parallel Aware": false,
"Async Capable": false,
"Scan Direction": "Forward",
"Index Name": "PK_c0117fdbc50b917ef9067740c44",
"Relation Name": "exif",
"Alias": "exif",
"Startup Cost": 0.15,
"Total Cost": 0.33,
"Plan Rows": 1,
"Plan Width": 434,
"Actual Startup Time": 0.017,
"Actual Total Time": 0.017,
"Actual Rows": 1,
"Actual Loops": 1,
"Index Cond": "(\"assetId\" = assets.id)",
"Rows Removed by Index Recheck": 0
}
]
}
]
},
{
"Node Type": "Aggregate",
"Strategy": "Plain",
"Partial Mode": "Simple",
"Parent Relationship": "SubPlan",
"Subplan Name": "SubPlan 1",
"Parallel Aware": false,
"Async Capable": false,
"Startup Cost": 13.74,
"Total Cost": 13.75,
"Plan Rows": 1,
"Plan Width": 32,
"Actual Startup Time": 0.142,
"Actual Total Time": 0.142,
"Actual Rows": 1,
"Actual Loops": 1,
"Plans": [
{
"Node Type": "Nested Loop",
"Parent Relationship": "Outer",
"Parallel Aware": false,
"Async Capable": false,
"Join Type": "Left",
"Startup Cost": 0.15,
"Total Cost": 13.72,
"Plan Rows": 1,
"Plan Width": 273,
"Actual Startup Time": 0.023,
"Actual Total Time": 0.029,
"Actual Rows": 2,
"Actual Loops": 1,
"Inner Unique": true,
"Plans": [
{
"Node Type": "Seq Scan",
"Parent Relationship": "Outer",
"Parallel Aware": false,
"Async Capable": false,
"Relation Name": "asset_faces",
"Alias": "asset_faces_1",
"Startup Cost": 0,
"Total Cost": 5.53,
"Plan Rows": 1,
"Plan Width": 116,
"Actual Startup Time": 0.014,
"Actual Total Time": 0.017,
"Actual Rows": 2,
"Actual Loops": 1,
"Filter": "(\"assetId\" = assets.id)",
"Rows Removed by Filter": 139
},
{
"Node Type": "Index Scan",
"Parent Relationship": "Inner",
"Parallel Aware": false,
"Async Capable": false,
"Scan Direction": "Forward",
"Index Name": "PK_5fdaf670315c4b7e70cce85daa3",
"Relation Name": "person",
"Alias": "person",
"Startup Cost": 0.15,
"Total Cost": 8.17,
"Plan Rows": 1,
"Plan Width": 173,
"Actual Startup Time": 0.005,
"Actual Total Time": 0.005,
"Actual Rows": 1,
"Actual Loops": 2,
"Index Cond": "(id = asset_faces_1.\"personId\")",
"Rows Removed by Index Recheck": 0
}
]
}
]
}
]
}
]
},
"Planning Time": 1.46,
"Triggers": [],
"Execution Time": 0.486
}
]
}
] Using subquery:Explain:[
{
"QUERY PLAN": "Limit (cost=19.06..32.83 rows=1 width=477)"
},
{
"QUERY PLAN": " -> Result (cost=19.06..32.83 rows=1 width=477)"
},
{
"QUERY PLAN": " -> Sort (cost=19.06..19.07 rows=1 width=445)"
},
{
"QUERY PLAN": " Sort Key: assets.\"fileCreatedAt\" DESC"
},
{
"QUERY PLAN": " -> Nested Loop (cost=8.90..19.05 rows=1 width=445)"
},
{
"QUERY PLAN": " Join Filter: (asset_faces.\"assetId\" = exif.\"assetId\")"
},
{
"QUERY PLAN": " -> Nested Loop (cost=8.75..18.71 rows=1 width=429)"
},
{
"QUERY PLAN": " -> GroupAggregate (cost=8.61..10.47 rows=1 width=16)"
},
{
"QUERY PLAN": " Group Key: asset_faces.\"assetId\""
},
{
"QUERY PLAN": " Filter: (count(DISTINCT asset_faces.\"personId\") = '2'::bigint)"
},
{
"QUERY PLAN": " -> Sort (cost=8.61..8.84 rows=94 width=32)"
},
{
"QUERY PLAN": " Sort Key: asset_faces.\"assetId\""
},
{
"QUERY PLAN": " -> Seq Scan on asset_faces (cost=0.00..5.53 rows=94 width=32)"
},
{
"QUERY PLAN": " Filter: (\"personId\" = ANY ('{fb80fce1-1e1d-4d5f-bdf1-316221ec8548,8b780879-189b-4dca-81a4-62c614680486}'::uuid[]))"
},
{
"QUERY PLAN": " -> Index Scan using \"PK_da96729a8b113377cfb6a62439c\" on assets (cost=0.15..8.17 rows=1 width=413)"
},
{
"QUERY PLAN": " Index Cond: (id = asset_faces.\"assetId\")"
},
{
"QUERY PLAN": " Filter: (\"isVisible\" AND (NOT \"isArchived\") AND (\"deletedAt\" IS NULL) AND (\"ownerId\" = ANY ('{fbf9fd06-5f1a-4924-9f7e-5e8625c62fa5}'::uuid[])))"
},
{
"QUERY PLAN": " -> Index Scan using \"PK_c0117fdbc50b917ef9067740c44\" on exif (cost=0.15..0.33 rows=1 width=434)"
},
{
"QUERY PLAN": " Index Cond: (\"assetId\" = assets.id)"
},
{
"QUERY PLAN": " SubPlan 1"
},
{
"QUERY PLAN": " -> Aggregate (cost=13.74..13.75 rows=1 width=32)"
},
{
"QUERY PLAN": " -> Nested Loop Left Join (cost=0.15..13.72 rows=1 width=273)"
},
{
"QUERY PLAN": " -> Seq Scan on asset_faces asset_faces_1 (cost=0.00..5.53 rows=1 width=116)"
},
{
"QUERY PLAN": " Filter: (\"assetId\" = assets.id)"
},
{
"QUERY PLAN": " -> Index Scan using \"PK_5fdaf670315c4b7e70cce85daa3\" on person (cost=0.15..8.17 rows=1 width=173)"
},
{
"QUERY PLAN": " Index Cond: (id = asset_faces_1.\"personId\")"
}
] Explain analyze: [
{
"QUERY PLAN": [
{
"Plan": {
"Node Type": "Limit",
"Parallel Aware": false,
"Async Capable": false,
"Startup Cost": 19.06,
"Total Cost": 32.83,
"Plan Rows": 1,
"Plan Width": 477,
"Actual Startup Time": 0.327,
"Actual Total Time": 0.329,
"Actual Rows": 1,
"Actual Loops": 1,
"Plans": [
{
"Node Type": "Result",
"Parent Relationship": "Outer",
"Parallel Aware": false,
"Async Capable": false,
"Startup Cost": 19.06,
"Total Cost": 32.83,
"Plan Rows": 1,
"Plan Width": 477,
"Actual Startup Time": 0.326,
"Actual Total Time": 0.328,
"Actual Rows": 1,
"Actual Loops": 1,
"Plans": [
{
"Node Type": "Sort",
"Parent Relationship": "Outer",
"Parallel Aware": false,
"Async Capable": false,
"Startup Cost": 19.06,
"Total Cost": 19.07,
"Plan Rows": 1,
"Plan Width": 445,
"Actual Startup Time": 0.162,
"Actual Total Time": 0.163,
"Actual Rows": 1,
"Actual Loops": 1,
"Sort Key": [
"assets.\"fileCreatedAt\" DESC"
],
"Sort Method": "quicksort",
"Sort Space Used": 27,
"Sort Space Type": "Memory",
"Plans": [
{
"Node Type": "Nested Loop",
"Parent Relationship": "Outer",
"Parallel Aware": false,
"Async Capable": false,
"Join Type": "Inner",
"Startup Cost": 8.9,
"Total Cost": 19.05,
"Plan Rows": 1,
"Plan Width": 445,
"Actual Startup Time": 0.14,
"Actual Total Time": 0.149,
"Actual Rows": 1,
"Actual Loops": 1,
"Inner Unique": true,
"Join Filter": "(asset_faces.\"assetId\" = exif.\"assetId\")",
"Rows Removed by Join Filter": 0,
"Plans": [
{
"Node Type": "Nested Loop",
"Parent Relationship": "Outer",
"Parallel Aware": false,
"Async Capable": false,
"Join Type": "Inner",
"Startup Cost": 8.75,
"Total Cost": 18.71,
"Plan Rows": 1,
"Plan Width": 429,
"Actual Startup Time": 0.111,
"Actual Total Time": 0.12,
"Actual Rows": 1,
"Actual Loops": 1,
"Inner Unique": true,
"Plans": [
{
"Node Type": "Aggregate",
"Strategy": "Sorted",
"Partial Mode": "Simple",
"Parent Relationship": "Outer",
"Parallel Aware": false,
"Async Capable": false,
"Startup Cost": 8.61,
"Total Cost": 10.47,
"Plan Rows": 1,
"Plan Width": 16,
"Actual Startup Time": 0.098,
"Actual Total Time": 0.106,
"Actual Rows": 1,
"Actual Loops": 1,
"Group Key": [
"asset_faces.\"assetId\""
],
"Filter": "(count(DISTINCT asset_faces.\"personId\") = '2'::bigint)",
"Rows Removed by Filter": 64,
"Plans": [
{
"Node Type": "Sort",
"Parent Relationship": "Outer",
"Parallel Aware": false,
"Async Capable": false,
"Startup Cost": 8.61,
"Total Cost": 8.84,
"Plan Rows": 94,
"Plan Width": 32,
"Actual Startup Time": 0.046,
"Actual Total Time": 0.049,
"Actual Rows": 69,
"Actual Loops": 1,
"Sort Key": [
"asset_faces.\"assetId\""
],
"Sort Method": "quicksort",
"Sort Space Used": 30,
"Sort Space Type": "Memory",
"Plans": [
{
"Node Type": "Seq Scan",
"Parent Relationship": "Outer",
"Parallel Aware": false,
"Async Capable": false,
"Relation Name": "asset_faces",
"Alias": "asset_faces",
"Startup Cost": 0,
"Total Cost": 5.53,
"Plan Rows": 94,
"Plan Width": 32,
"Actual Startup Time": 0.008,
"Actual Total Time": 0.021,
"Actual Rows": 69,
"Actual Loops": 1,
"Filter": "(\"personId\" = ANY ('{fb80fce1-1e1d-4d5f-bdf1-316221ec8548,8b780879-189b-4dca-81a4-62c614680486}'::uuid[]))",
"Rows Removed by Filter": 72
}
]
}
]
},
{
"Node Type": "Index Scan",
"Parent Relationship": "Inner",
"Parallel Aware": false,
"Async Capable": false,
"Scan Direction": "Forward",
"Index Name": "PK_da96729a8b113377cfb6a62439c",
"Relation Name": "assets",
"Alias": "assets",
"Startup Cost": 0.15,
"Total Cost": 8.17,
"Plan Rows": 1,
"Plan Width": 413,
"Actual Startup Time": 0.011,
"Actual Total Time": 0.012,
"Actual Rows": 1,
"Actual Loops": 1,
"Index Cond": "(id = asset_faces.\"assetId\")",
"Rows Removed by Index Recheck": 0,
"Filter": "(\"isVisible\" AND (NOT \"isArchived\") AND (\"deletedAt\" IS NULL) AND (\"ownerId\" = ANY ('{fbf9fd06-5f1a-4924-9f7e-5e8625c62fa5}'::uuid[])))",
"Rows Removed by Filter": 0
}
]
},
{
"Node Type": "Index Scan",
"Parent Relationship": "Inner",
"Parallel Aware": false,
"Async Capable": false,
"Scan Direction": "Forward",
"Index Name": "PK_c0117fdbc50b917ef9067740c44",
"Relation Name": "exif",
"Alias": "exif",
"Startup Cost": 0.15,
"Total Cost": 0.33,
"Plan Rows": 1,
"Plan Width": 434,
"Actual Startup Time": 0.011,
"Actual Total Time": 0.012,
"Actual Rows": 1,
"Actual Loops": 1,
"Index Cond": "(\"assetId\" = assets.id)",
"Rows Removed by Index Recheck": 0
}
]
}
]
},
{
"Node Type": "Aggregate",
"Strategy": "Plain",
"Partial Mode": "Simple",
"Parent Relationship": "SubPlan",
"Subplan Name": "SubPlan 1",
"Parallel Aware": false,
"Async Capable": false,
"Startup Cost": 13.74,
"Total Cost": 13.75,
"Plan Rows": 1,
"Plan Width": 32,
"Actual Startup Time": 0.161,
"Actual Total Time": 0.161,
"Actual Rows": 1,
"Actual Loops": 1,
"Plans": [
{
"Node Type": "Nested Loop",
"Parent Relationship": "Outer",
"Parallel Aware": false,
"Async Capable": false,
"Join Type": "Left",
"Startup Cost": 0.15,
"Total Cost": 13.72,
"Plan Rows": 1,
"Plan Width": 273,
"Actual Startup Time": 0.034,
"Actual Total Time": 0.039,
"Actual Rows": 2,
"Actual Loops": 1,
"Inner Unique": true,
"Plans": [
{
"Node Type": "Seq Scan",
"Parent Relationship": "Outer",
"Parallel Aware": false,
"Async Capable": false,
"Relation Name": "asset_faces",
"Alias": "asset_faces_1",
"Startup Cost": 0,
"Total Cost": 5.53,
"Plan Rows": 1,
"Plan Width": 116,
"Actual Startup Time": 0.023,
"Actual Total Time": 0.026,
"Actual Rows": 2,
"Actual Loops": 1,
"Filter": "(\"assetId\" = assets.id)",
"Rows Removed by Filter": 139
},
{
"Node Type": "Index Scan",
"Parent Relationship": "Inner",
"Parallel Aware": false,
"Async Capable": false,
"Scan Direction": "Forward",
"Index Name": "PK_5fdaf670315c4b7e70cce85daa3",
"Relation Name": "person",
"Alias": "person",
"Startup Cost": 0.15,
"Total Cost": 8.17,
"Plan Rows": 1,
"Plan Width": 173,
"Actual Startup Time": 0.006,
"Actual Total Time": 0.006,
"Actual Rows": 1,
"Actual Loops": 2,
"Index Cond": "(id = asset_faces_1.\"personId\")",
"Rows Removed by Index Recheck": 0
}
]
}
]
}
]
}
]
},
"Planning Time": 0.953,
"Triggers": [],
"Execution Time": 0.455
}
]
}
] Diff:95,96c95,96
< "Actual Startup Time": 0.334,
< "Actual Total Time": 0.336,
---
> "Actual Startup Time": 0.327,
> "Actual Total Time": 0.329,
109,110c109,110
< "Actual Startup Time": 0.333,
< "Actual Total Time": 0.335,
---
> "Actual Startup Time": 0.326,
> "Actual Total Time": 0.328,
123,124c123,124
< "Actual Startup Time": 0.188,
< "Actual Total Time": 0.189,
---
> "Actual Startup Time": 0.162,
> "Actual Total Time": 0.163,
144,145c144,145
< "Actual Startup Time": 0.155,
< "Actual Total Time": 0.164,
---
> "Actual Startup Time": 0.14,
> "Actual Total Time": 0.149,
162,163c162,163
< "Actual Startup Time": 0.117,
< "Actual Total Time": 0.126,
---
> "Actual Startup Time": 0.111,
> "Actual Total Time": 0.12,
179,180c179,180
< "Actual Startup Time": 0.107,
< "Actual Total Time": 0.115,
---
> "Actual Startup Time": 0.098,
> "Actual Total Time": 0.106,
198,199c198,199
< "Actual Startup Time": 0.058,
< "Actual Total Time": 0.061,
---
> "Actual Startup Time": 0.046,
> "Actual Total Time": 0.049,
244,245c244,245
< "Actual Startup Time": 0.009,
< "Actual Total Time": 0.009,
---
> "Actual Startup Time": 0.011,
> "Actual Total Time": 0.012,
268,269c268,269
< "Actual Startup Time": 0.017,
< "Actual Total Time": 0.017,
---
> "Actual Startup Time": 0.011,
> "Actual Total Time": 0.012,
291,292c291,292
< "Actual Startup Time": 0.142,
< "Actual Total Time": 0.142,
---
> "Actual Startup Time": 0.161,
> "Actual Total Time": 0.161,
306,307c306,307
< "Actual Startup Time": 0.023,
< "Actual Total Time": 0.029,
---
> "Actual Startup Time": 0.034,
> "Actual Total Time": 0.039,
323,324c323,324
< "Actual Startup Time": 0.014,
< "Actual Total Time": 0.017,
---
> "Actual Startup Time": 0.023,
> "Actual Total Time": 0.026,
343,344c343,344
< "Actual Startup Time": 0.005,
< "Actual Total Time": 0.005,
---
> "Actual Startup Time": 0.006,
> "Actual Total Time": 0.006,
358c358
< "Planning Time": 1.46,
---
> "Planning Time": 0.953,
360c360
< "Execution Time": 0.486
---
> "Execution Time": 0.455 |
Replaces the hasPeople and hasPeopleCte helper functions used for filtering when searching for people or getting time buckets for a person with a single helper function to join on a subquery instead of adding a CTE and then joining on it.
I noticed the awkward ergonomics of using a CTE for this when adding a similar helper function for filtering by tags in this PR (#15395).
The CTE needs to be added before calling selectFrom but the innerJoin needs to happen after. This either results in the logic for filtering being split up in two parts using hasPeopleCte, as seen in getTimeBuckets, or in a single call to hasPeople which hides this split but also has to include the selectFrom('assets') which is unexpected for a function called hasPeople.
Additionally, because hasPeople includes the selectFrom it can only be called once per query and is therefore incompatible with other functions that would want to do the same thing (e.g. a hasTags).
I think the new hasPeople function using a subquery is better as it doesn't have these awkward ergonomics and also it is more consistent with how other things are filtered like withAlbums in getTimeBuckets and a potential hasTags function if my other PR gets merged.