Merge lp:~wgrant/launchpad/bug-1007140 into lp:launchpad

Proposed by William Grant
Status: Merged
Approved by: Curtis Hovey
Approved revision: no longer in the source branch.
Merged at revision: 15935
Proposed branch: lp:~wgrant/launchpad/bug-1007140
Merge into: lp:launchpad
Diff against target: 32 lines (+6/-3)
1 file modified
lib/lp/code/model/branch.py (+6/-3)
To merge this branch: bzr merge lp:~wgrant/launchpad/bug-1007140
Reviewer Review Type Date Requested Status
Curtis Hovey (community) code Approve
Review via email: mp+123688@code.launchpad.net

Commit message

Tweak get_branch_privacy_filter to use the array intersection trick to match Branch.access_policy, convincing postgres to pull it up two levels and fix performance for users with lots of teams.

Description of the change

This branch tweaks get_branch_privacy_filter to outsmart the query planner. See https://bugs.launchpad.net/launchpad/+bug/1007140/comments/1 for details/explains, but basically PostgreSQL was severely misplanning some complex branch queries for people with lots of teams, and slightly misplanning for people with not many teams. By replacing the traditional IN with an array intersection operation, the planner somehow realises the inner subquery is uncorrelated and is able to pull it right out to the top. This makes a number of BMP queries 10-200x faster, and leaves the already good queries just as quick.

To post a comment you must log in.
Revision history for this message
Curtis Hovey (sinzui) wrote :

Thank you.

review: Approve (code)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'lib/lp/code/model/branch.py'
2--- lib/lp/code/model/branch.py 2012-09-05 21:51:06 +0000
3+++ lib/lp/code/model/branch.py 2012-09-11 08:03:23 +0000
4@@ -170,6 +170,7 @@
5 sqlvalues,
6 )
7 from lp.services.database.stormexpr import (
8+ Array,
9 ArrayAgg,
10 ArrayIntersects,
11 )
12@@ -1622,15 +1623,17 @@
13 where=(TeamParticipation.person == user)
14 )), False)
15
16- policy_grant_query = branch_class.access_policy.is_in(
17+ policy_grant_query = Coalesce(
18+ ArrayIntersects(
19+ Array(branch_class.access_policy),
20 Select(
21- AccessPolicyGrant.policy_id,
22+ ArrayAgg(AccessPolicyGrant.policy_id),
23 tables=(AccessPolicyGrant,
24 Join(TeamParticipation,
25 TeamParticipation.teamID ==
26 AccessPolicyGrant.grantee_id)),
27 where=(TeamParticipation.person == user)
28- ))
29+ )), False)
30
31 return [
32 Or(public_branch_filter, artifact_grant_query, policy_grant_query)]