Merge lp:~adeuring/launchpad/bug-799785 into lp:launchpad

Proposed by Abel Deuring
Status: Merged
Approved by: Abel Deuring
Approved revision: no longer in the source branch.
Merged at revision: 13274
Proposed branch: lp:~adeuring/launchpad/bug-799785
Merge into: lp:launchpad
Diff against target: 26 lines (+3/-5)
1 file modified
lib/lp/registry/model/distribution.py (+3/-5)
To merge this branch: bzr merge lp:~adeuring/launchpad/bug-799785
Reviewer Review Type Date Requested Status
Graham Binns (community) code Approve
Review via email: mp+65373@code.launchpad.net

Commit message

[r=gmb][bug=799785] Faster evaluation of Distribution.has_published_sources

Description of the change

This branch fixes bug 799785: Timeout when trying to set the translation focus for Ubuntu

The OOPS report from this bug shows one very long query, which is issued in Snapshot(distribution), called in lp.app.browser.launchpadform.LaunchpadEditFormView.updateContextFromData(), when Distribution.has_published_sources is evaluated.

The query is a UNION of two subqueries; an EXPLAIN ANALYZE on staging (thanks Deryck!) of it showed:

- one of the sub-queries needed 14 seconds; the other sub-query needed <20 milliseconds.
- the first sub-query needed 10 seconds (or even more -- I did not look that carefully at every line of the EXPLAIN ANALYZE output..,) to sort the result.
- Merging and sorting the two sub-queries required an external disk merge, occupying 46912kB; it took 7 seconds.

The property Distribution.has_published_sources tells us, if _any_ published source exists, so we really do not need all the sorting and merging of sub-queries.

Another run of EXPLAIN ANALZYE of only the first, originally slow, query, but now originating from

   archive.getPublishedSources().order_by().is_empty()

needed < 40 milliseoncds.

So we can simply loop over self.all_distro_archives, and leave the loop early for the first non-empty result set.

Since we have just two archive_sources even for Ubuntu, I am not concerned about a slow loop execution, caused by a loop over a large number of empty archive_sources for any distribution.

I did not add any test (not sure if we can properly test SQL performance...); the existing short test in lib/lp/registry/doc/distribution.txt still passes.

So, just one existing check:

./bin/test registry -vvt doc.distribution.txt

no lint

To post a comment you must log in.
Revision history for this message
Graham Binns (gmb) :
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/registry/model/distribution.py'
2--- lib/lp/registry/model/distribution.py 2011-06-17 19:47:36 +0000
3+++ lib/lp/registry/model/distribution.py 2011-06-21 16:35:53 +0000
4@@ -30,7 +30,6 @@
5 SQL,
6 )
7 from storm.store import (
8- EmptyResultSet,
9 Store,
10 )
11 from zope.component import getUtility
12@@ -1850,11 +1849,10 @@
13
14 @property
15 def has_published_sources(self):
16- archives_sources = EmptyResultSet()
17 for archive in self.all_distro_archives:
18- archives_sources = archives_sources.union(
19- archive.getPublishedSources())
20- return not archives_sources.is_empty()
21+ if not archive.getPublishedSources().order_by().is_empty():
22+ return True
23+ return False
24
25
26 class DistributionSet: