Stewart Smith [Fri, 10 Aug 2018 08:00:57 +0000 (18:00 +1000)]
4x performance improvement for viewing patch with many comments
Using the example of id:20180720035941.6844-1-khandual@linux.vnet.ibm.com
with my test dataset of a chunk of a variety of mailing lists, has
this cover letter have 67 comments from a variety of people. Thus,
it's on the larger side of things.
Originally, displaying the /patch/550/ for this (redirected to /cover)
would take 81 SQL queries in ~60ms on my laptop.
After this optimisation, it's down to 14 queries in 14ms.
When the cache is cold, it's down to 32ms from 83ms.
The effect of this patch is to execute a join in the database to
get the submitter information for each comment at the same time as
getting all the comments rather than doing a one-by-one lookup after
the fact.
Signed-off-by: Stewart Smith <stewart@linux.ibm.com> Reviewed-by: Stephen Finucane <stephen@that.guru>
Stewart Smith [Fri, 10 Aug 2018 08:00:56 +0000 (18:00 +1000)]
Improve patch listing performance (~3x)
There's two main bits that are really expensive when composing the list
of patches for a project: the query getting the list, and the query
finding the series for each patch.
If we look at the query getting the list, it gets a lot of unnecessary
fields such as 'headers' and 'content', even though we tell Django not
to. It turns out that Django seems to ignore the Submission relationship
and I have no idea how to force it to ignore that thing (defer doesn't
work) but if we go only, then it works okay.
From my import of ~8000 messages for a few projects, my laptop query
time (MySQL, as setup by whatever the docker-compose things do) goes
from:
The big jump is the patches.only change, and the removal of ordering
on the patchseries takes a further 10ms off. For some strange reason, it
seems rather hard to tell Django that you don't care what order the
results come back in for that query (if we do, then the db server has to
do a sort rather than just return each row)
Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
[stephenfin: Add missing migration that had been squashed into a later
migration] Signed-off-by: Stephen Finucane <stephen@that.guru>
Andrew Donnellan [Sun, 26 Aug 2018 10:56:05 +0000 (20:56 +1000)]
docs: Fix documentation of REST_RESULTS_PER_PAGE setting
In 8fe11180a1a5 ("REST: Add new setting for maximum API page size") I
accidentally deleted the versionadded information for
REST_RESULTS_PER_PAGE. Restore it.
Fixes: 8fe11180a1a5 ("REST: Add new setting for maximum API page size") Signed-off-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com> Signed-off-by: Daniel Axtens <dja@axtens.net>
Andrew Donnellan [Tue, 24 Jul 2018 05:10:51 +0000 (15:10 +1000)]
REST: Add new setting for maximum API page size
In 41790caf59ad ("REST: Limit max page size") we limited the maximum page
size to the default page size in the settings.
This turns out to be rather restrictive, as we usually want to keep the
default page size low, but an administrator may want to allow API clients
to fetch more than that per request.
Add a new setting, MAX_REST_RESULTS_PER_PAGE, to set the maximum page size.
Closes: #202 ("Separate max API page size and default API page size into different settings") Suggested-by: Stewart Smith <stewart@linux.ibm.com> Suggested-by: Joel Stanley <joel@jms.id.au> Signed-off-by: Andrew Donnellan <andrew.donnellan@au1.ibm.com>
[dja: set to 250 as per mailing list discussion] Signed-off-by: Daniel Axtens <dja@axtens.net>
Stephen Finucane [Sun, 24 Jun 2018 19:55:57 +0000 (20:55 +0100)]
docker: Don't require rebuilding if unnecessary
Now that we're pinning versions, we're going to see more frequent
dependency version changes. Requiring a rebuild after every one of these
is tiresome so don't force it and instead display a helpful message
merely suggesting that a rebuild may be necessary.
Signed-off-by: Stephen Finucane <stephen@that.guru> Cc: Daniel Axtens <dja@axtens.net> Acked-by: Daniel Axtens <dja@axtens.net>
[dja: we're not currently pinning versions because I dropped that
patch as it broke postgres. But this can stay - sfin has been
asking for it for ages.] Signed-off-by: Daniel Axtens <dja@axtens.net>
Stephen Finucane [Sun, 24 Jun 2018 19:55:56 +0000 (20:55 +0100)]
tox: Rework warning infrastructure
Python 3.5's xmlrpc spews lots of ResourceWarnings that go
away in 3.6, so silence them.
We also see some warnings from inside the import machinery,
which we also silence.
Signed-off-by: Stephen Finucane <stephen@that.guru>
[dja: make slightly more restrictive, reword commit message] Signed-off-by: Daniel Axtens <dja@axtens.net>
Stephen Finucane [Sun, 24 Jun 2018 19:55:53 +0000 (20:55 +0100)]
Add support for Django 2.0
Nothing too complicated here except for the addition of a new compat
wrapper, which will be removed again shortly. According to the Django
release notes, Django should function with Python 3.4. However, it was
not possible to get this functioning due to the below error:
Traceback (most recent call last):
File ".../patchwork/manage.py", line 11, in <module>
...
File ".../django/db/models/fields/related.py", line 313, in contribute_to_class
'app_label': cls._meta.app_label.lower(),
TypeError: unsupported operand type(s) for %: 'bytes' and 'dict'
This does not appear to be an issue with Patchwork but the exact root
cause has not been identified. As a result, only Python 3.5 and 3.6 are
marked as supported for this Django version.
As this is the first Python 3-only dependency we have, we need to start
making use of the 'python_version' environment marker.
Signed-off-by: Stephen Finucane <stephen@that.guru> Signed-off-by: Daniel Axtens <dja@axtens.net>
Stephen Finucane [Sun, 24 Jun 2018 19:55:47 +0000 (20:55 +0100)]
REST: Check.user is not read-only
We only support 'Check' creation - not check updating. As a result,
there's no real reason that the 'Check.user' field should be read-only
and this is causing an issue with Django REST Framework 3.7. Simply
remove the attribute and extend the tests to validate things are working
as expected.
Signed-off-by: Stephen Finucane <stephen@that.guru> Reviewed-by: Daniel Axtens <dja@axtens.net> Signed-off-by: Daniel Axtens <dja@axtens.net>
Daniel Black [Mon, 6 Aug 2018 06:56:37 +0000 (16:56 +1000)]
travis: test against postgresql 10 and 11
postgresql 10 is the most recent major version, and it would be
good to keep an eye on postgres 11 compatibility also, so test
against both of those.
Specify PGPORT as a way to differentiate the new installations
from the postgres 9.6 server running on the default port (5432).
Use a local unix socket to work around the fact that by default
postgres only allows passwordless auth on local sockets - which
is tweaked for postgres 9.6 but not for later versions that aren't
in the usual Travis image.
Also print the current db version and user for validation.
Signed-off-by: Daniel Black <daniel@linux.ibm.com>
[cleanup, squash, commit message] Signed-off-by: Daniel Axtens <dja@axtens.net>
Jiri Benc [Thu, 28 Jun 2018 19:42:11 +0000 (15:42 -0400)]
parser: fix parsing of patches with headings
Some people tend to use lines full of '=' as a fancy way to format headings
in their commit messages in a rst-like style. However, the current parser
treats such lines as a beginning of a diff.
The only currently used tool that produces diffs with '=' lines is quilt in
the default configuration. However, even with quilt, the diff looks this
way:
It's enough to match on the "Index:" line. The state of the state machine is
kept at 1 when it encounters the '=' line, thus it's safe to remove the
match on '=' completely.
[This prevents us from properly parsing metadata out of the changelog. -dcz ]
Signed-off-by: Jiri Benc <jbenc@redhat.com> Reviewed-by: Stephen Finucane <stephen@that.guru>
Yuri Volchkov [Wed, 20 Jun 2018 12:21:42 +0000 (14:21 +0200)]
parsemail: ignore html part of multi-part comments
Currently an html-protection present only for patch-emails. If a
multi-part comment-email arrives, it messes up patchwork. In my case,
the symptom was a non intended 'Signed-off-by' in the downloaded
patches, with html-like junk.
This patch makes parsemail skip all parts of comment which are not
text/plain.
Of course, this will drop html-only emails completely. But they can
not be parsed anyways.
Signed-off-by: Yuri Volchkov <yuri.volchkov@gmail.com> Reviewed-by: Stephen Finucane <stephen@that.guru>
This provides an easy way for clients to navigate to the web view. The
URL is added to four resources: bundles, comments, cover letters and
series. We could also extend this to projects and users in the future,
but the latter would require renaming an existing property while the
latter would require a public "user" page which does not currently
exists.
Signed-off-by: Stephen Finucane <stephen@that.guru> Reviewed-by: Daniel Axtens <dja@axtens.net>
Stephen Finucane [Wed, 13 Jun 2018 21:53:22 +0000 (22:53 +0100)]
Don't discard values from 'archive' filter
The pagination functionality used in the 'patchwork.view.generic_list'
generates the filter querystring from scratch. To do this, it calls the
'patchwork.filters.Filters.params' function, which in turn calls the
'patchwork.filters.Filter.key' function for each filter. If any of these
'key' functions return None, the relevant filter is not included in the
querystring. This ensures we don't end up with a load of filters like
the below:
There is one exception to this rule, however: ArchiveFilter. This is a
little unusual in that it is active by default, excluding patches that
are "archived" from the list. As a result, the 'key' function should
return None for this active state, not for the disabled state. This has
been the case up until commit d848f046 which falsely equated 'is False'
with 'is None'. This small typo resulted in the filter being ignored
when generating pagination links and essentially broke pagination for
some use cases.
Fix this up. We could probably simplify this thing greatly by not
recalculating filters for pagination at least or, better yet, by using
django-filter here too. That is a change for another day though.
Signed-off-by: Stephen Finucane <stephen@that.guru> Reported-by: John McNamara <john.mcnamara@intel.com> Reported-by: Eli Schwartz <eschwartz93@gmail.com> Fixes: d848f046 ("trivial: Don't shadow built-ins") Closes: #184
views: Raise 404 if downloading non-existent dependencies
If a patch was processed by Patchwork before series support was added,
it will not have a series associated with it. As a result, it is not
possible to extract the dependencies for that patch from the series and
a 404 should be raised. This was not previously handled correctly.
Signed-off-by: Stephen Finucane <stephen@that.guru> Reviewed-by: Daniel Axtens <dja@axtens.net> Reported-by: John McNamara <john.mcnamara@intel.com> Fixes: e2dfd490 ("views: Add 'series' parameter to '/mbox' endpoint") Closes: #189
docs: Update deployment installation guide for v2.1
There are no actual changes needed from the Patchwork side so this is
mostly a cleanup.
- Use Ubuntu 18.04 (including package names)
- Resolve some minor issues with commands
- Remove use of "trust" authentication for PostgreSQL
- Minor style changes
Signed-off-by: Stephen Finucane <stephen@that.guru>
Stephen Finucane [Wed, 30 May 2018 10:57:59 +0000 (11:57 +0100)]
sql: Update 'grant-all.mysql' script with missing tables
These were all introduced in 2.0 and while the postgreSQL script was
fixed in commit 234bc7c3, the MySQL one was not. This suggests either
(a) no one is using this or (b) people are carrying local changes but
for now we just resolve the issues.
Signed-off-by: Stephen Finucane <stephen@that.guru>
Daniel Axtens [Fri, 11 May 2018 17:00:44 +0000 (03:00 +1000)]
REST: Disable control for filtering patches by series in web view
As with the events view, creating and rendering the control for
filtering patches by series creates a massive slowdown. It's a little
sad not to be able to do this in the web UI as filtering patches
by series does make sense, but hopefully people figure out you can
still do it, just not from the web view.
Signed-off-by: Daniel Axtens <dja@axtens.net> Signed-off-by: Stephen Finucane <stephen@that.guru>
docs: Add additional information about API versions
As we're soon going to be supporting a v1.1 API, we should document what
versions are available and whether they're supported still (hint: we
support both v1.0 and v1.1 at present).
Signed-off-by: Stephen Finucane <stephen@that.guru> Signed-off-by: Daniel Axtens <dja@axtens.net>
The root cause of this performance issue was not the use of the
JSONRenderer but rather the population of filter forms. The latter is
now disabled, meaning we can start using the original renderer.
Signed-off-by: Stephen Finucane <stephen@that.guru> Cc: Daniel Axtens <dja@axtens.net> Acked-by: Daniel Axtens <dja@axtens.net> Signed-off-by: Daniel Axtens <dja@axtens.net>
Stephen Finucane [Thu, 10 May 2018 14:45:05 +0000 (15:45 +0100)]
REST: Resolve performance issues with '/events' web view
The dropdown select-based filters in the web view of the REST API have
stung us a few times. In this case, populating these filters for the
'/events' endpoint results in a huge query that hammers the database and
results in seriously laggy responses.
The root cause of this performance issues was erroneously identified as
an issue with the JSON renderer so that particular patch can now be
reverted. This will be done separately.
Signed-off-by: Stephen Finucane <stephen@that.guru> Cc: Daniel Axtens <dja@axtens.net> Tested-by: Daniel Axtens <dja@axtens.net> Signed-off-by: Daniel Axtens <dja@axtens.net>
Stephen Finucane [Wed, 11 Apr 2018 16:13:38 +0000 (17:13 +0100)]
REST: Use DRF-specific filterset
This variant of 'FilterSet' will convert a 'django.forms.ValidationError',
which wouldn't be handled by DRF, to a
'rest_framework.exceptions.ValidationError', which would be.
Signed-off-by: Stephen Finucane <stephen@that.guru>
[dja: commit message] Signed-off-by: Daniel Axtens <dja@axtens.net>
Stephen Finucane [Wed, 11 Apr 2018 16:13:36 +0000 (17:13 +0100)]
REST: Rename Filter -> FilterSet
FilterSets are to Forms as Filters are to Fields: the former is
made up of the latter. We have a FilterSet for each resource that we
wish to support filtering on (i.e. all of them).
Rename our "Filters" to the more appropriate FilterSets.
The old name was confusing and will conflict with some forthcoming changes.
Signed-off-by: Stephen Finucane <stephen@that.guru>
[dja: commit message] Signed-off-by: Daniel Axtens <dja@axtens.net>
Signed-off-by: Stephen Finucane <stephen@that.guru> Fixes: 81e6f8e4 ("docs: Prepare for 2.1.0-rc1") Cc: Daniel Axtens <dja@axtens.net> Signed-off-by: Daniel Axtens <dja@axtens.net>
Yuri Volchkov [Mon, 7 May 2018 15:57:55 +0000 (01:57 +1000)]
skip original Content-Transfer-Encoding for mbox
In the commit 01b9cbb9 all original mail headers are copied into the
resulted mbox file. This means that some headers are going to be
present twice in the generated mbox. That is fine unless the original
email arrived in base64 encoding.
Apparently git relies on the latest Content-Transfer-Encoding key. And
since downloaded patch's actual encoding is '7bit', git fails to apply
it with the message 'Patch is empty'.
Since patchwork adds a proper 'Content-Transfer-Encoding' anyways,
let's skip this field while copying headers from the original mail
Explicitly distinguish between comments on patch and cover
reverse() gets confused when the same view name and kwargs are passed to
it, ignoring what endpoint the request originated from. Fix this by
using different view names for cover letter and patch comments views.
Reported-by: Daniel Axtens <dja@axtens.net> Signed-off-by: Veronika Kabatova <vkabatov@redhat.com> Reviewed-by: Stephen Finucane <stephen@that.guru>
Daniel Axtens [Mon, 30 Apr 2018 15:44:59 +0000 (01:44 +1000)]
parsemail: Clarify exit codes
jk reports that the patchwork error codes are really unhelpful for
correct integration with an MDA. In particular they make sorting out
failures into a separate queue very difficult. Make this better and
clearer: only return 1 on a genuinely unexpected case that requires
adminstrator intervention.
Update the comment for parse_mail regarding return values and exceptions
to line up with how the function actually works and how we use the
results.
Update the tests. None of the existing tests should exit 1; they're
all 'expected' failures: unknown project etc. Also we removed the
exit(0) from the success path, so stop expecting that exception to
be raised.
Add a test for duplicates. That should also succeed without raising
an exception: dups are part of life.
Update parsearchive to deal with the fact that we can no longer
differentiate duplicates.
Reported-by: Jeremy Kerr <jk@ozlabs.org> Fixes: #171 Signed-off-by: Daniel Axtens <dja@axtens.net> Reviewed-by: Stephen Finucane <stephen@that.guru>
Stephen Finucane [Tue, 17 Apr 2018 08:58:00 +0000 (09:58 +0100)]
docker-compose: Switch to 3.0 syntax
Ubuntu 18.04 (Bionic Beaver) providers 'docker-compose' 1.17.1 [1] at
release which supports the 3.0 syntax [2]. Using this allows some users
(me) to resolve a long standing issue caused by a UID that's not 1000.
Stephen Finucane [Tue, 17 Apr 2018 08:50:44 +0000 (09:50 +0100)]
tests: Remove Selenium tests
These were added quite some time ago in order to allow some level of UI
testing. However, I've personally never used them, they're not used by
the CI, and no one has shown any desire in extending them in their time
here. It is time to bid these tests adieu.
Removing these allows us to remove a whole load of wiring that existed
just to enable these. Some of this, like the '--quick-tox' option for
the Dockerfile, is retained so we don't need to use different commands
for various versions of Patchwork, but the majority is just stripped
out.
Signed-off-by: Stephen Finucane <stephen@that.guru> Cc: Daniel Axtens <dja@axtens.net>
While the code on our side returns all (key, value) pairs for email
headers, Django's REST framework probably uses dictionaries behind the
scenes. This means that having multiple headers with same key (eg
'Received', which is totally valid and common situation), only one of
these headers is visible in the REST API.
Let's hack around this by returning a list of values in case the key is
present multiple times.
Signed-off-by: Veronika Kabatova <vkabatov@redhat.com> Reviewed-by: Stephen Finucane <stephen@that.guru>
Stephen Finucane [Tue, 17 Apr 2018 08:37:44 +0000 (09:37 +0100)]
tests: Replace incorrect tests
In commit 683792d1, the 'test_api.py' was split into multiple
'api/test_xyz.py' files. As part of this change, the tests for cover
letter were mistakenly included in place of tests for checks. Correct
this oversight.
Stephen Finucane [Wed, 11 Apr 2018 16:36:18 +0000 (17:36 +0100)]
tox: Add 'docs' to default environments
I'd simply run 'tox' (via docker) to validate some previous patches.
Sadly that didn't catch a release note issue. Make sure this doesn't
happen again by always running 'docs'.
Signed-off-by: Stephen Finucane <stephen@that.guru> Signed-off-by: Daniel Axtens <dja@axtens.net>
Bundle tests got broken after the subject in mbox was changed from the
parsed version to the original one because the tests checked for the
presence of patch's name in the response. Fixing this turned out to be
a bit tricky since the tests check the mbox attachment and HTML
responses separately, so we need a string that would be present in both
(the intuitive idea of checking X-Patchwork-Id won't work well).
Add the patch's name to the content of the test patch so we can continue
testing things the same way, checking for the presence of patch's name.
Also add a releasenote notifying about the inclusion of the original
headers.
Reverts: b2a25342 ("Use parsed subject for mboxes") Fixes: 01b9cbb9 ("Include all email headers in mboxes") Signed-off-by: Veronika Kabatova <vkabatov@redhat.com> Reviewed-by: Stephen Finucane <stephen@that.guru>
Stephen Finucane [Sun, 25 Mar 2018 18:28:21 +0000 (19:28 +0100)]
docs: Add information on REST API versioning
This isn't too prescriptive, given that so far we've only dealt with
adding new fields. However, it should serve as a guide to alert devs
that this stuff exists and should be a concern.
Signed-off-by: Stephen Finucane <stephen@that.guru>
Stephen Finucane [Sun, 25 Mar 2018 18:28:20 +0000 (19:28 +0100)]
REST: Use versioning for modified responses
This ensures clients are getting a consistent response if they request
the old version of the API. We do this by way of extensions to the
'HyperlinkedModelSerializer' class rather than duplicating the
serializers as it results in far less duplication. This approach won't
work for a MAJOR version bump but, all going well, it will be a while
before we have to deal with one of these.
The only two fields added since API 1.0 was released, 'cover.mbox' and
'project.subject_match', are handled accordingly.
Signed-off-by: Stephen Finucane <stephen@that.guru>
With a recent change, we started using the original subject header
instead of the one we had already cleaned up at the parsing stage.
Revert this aspect of that change.
Signed-off-by: Stephen Finucane <stephen@that.guru> Fixes: 01b9cbb9 ("Include all email headers in mboxes")
Solves issue #165 (Exported mboxes should include In-Reply-To,
References, etc headers). Instead of including only a few chosen ones,
all received headers are added to mboxes.
Signed-off-by: Veronika Kabatova <vkabatov@redhat.com> Reviewed-by: Stephen Finucane <stephen@that.guru>
The docs suggested to account for git prefixes (a/, b/) using eg.
?/patchwork/views/*. My rules didn't work so I tried bare path
(patchwork/views/*) instead. Looking at the code, the prefix really is
striped away (filename = '/'.join(filename.split('/')[1:])). Fix the
documentation to reflect on what is really happening.
Signed-off-by: Veronika Kabatova <vkabatov@redhat.com>
[dja: see 7bb0ebd78ff7 ("parser: Add patch_get_filenames()")] Signed-off-by: Daniel Axtens <dja@axtens.net>
Daniel Axtens [Tue, 20 Mar 2018 22:34:15 +0000 (09:34 +1100)]
docker: set timezone to Australia/Canberra
The tzinfo package isn't installed in docker, which makes the
default timezone UTC. This is unfortunate: the Django TZ in
settings/base.py is Australia/Canberra, and having a non-UTC
TZ is good for exposing faulty assumptions about what is and
isn't UTC.
Signed-off-by: Daniel Axtens <dja@axtens.net> Reviewed-by: Stephen Finucane <stephen@that.guru>
Daniel Axtens [Mon, 12 Mar 2018 12:08:54 +0000 (23:08 +1100)]
api: Only provide JSON version of events list
Something is very, very slow in the d-r-f browsable API events renderer.
In my MySQL test (~33k patches), the CPU time to render the events list
is ~11s, and the time taken by SQL queries is only ~3s. If the JSON
renderer is used, that drops to 0.2s for the entire page (because less
CPU is used, and - for some as yet unknown reason - a *very* expensive
db query is dropped.)
In my PostgreSQL test (~100k patches), the results are even more stark:
30s of CPU time and 0.2s of DB time goes to 0.25s for the entire page.
Something is seriously, seriously wrong with whatever d-r-f is doing.
So, simply render the event list as unlinked JSON for now.
There are a few followups we should do, but this is an important start -
no-one should be able to DoS a patchwork server by just enumerating the
events!
In particular, we should find out:
- why postgres and mysql behaviour is so different.
- what on earth d-r-f is doing that makes rendering the pretty-printed
version so incredibly slow.
Daniel Axtens [Mon, 12 Mar 2018 11:07:15 +0000 (22:07 +1100)]
api: EventList: change select_related() to prefetch_related()
select_related() creates a single giant query that JOINs the required
tables together in the DB. prefetch_related() does a similar thing,
but at the Django layer - for all referenced models, it makes a
separate query to the DB to fetch them.
This massively, massively simplifies the job the DB has to do:
instead of creating a massive, sparse results table with many
columns, we do 1 query for the events, and then query for only
patches/cover letters/series/projects etc referenced in those 30
events.
Tested with cURL + JSON renderer + Postgres w/ ~100k patches,
request time went from 1.5s to 0.25s, a 6x speedup.
Tested with cURL + JSON renderer + MySQL w/ ~33k patches,
request time went from ~2.2s to ~0.20s, an ~11x speedup.
Daniel Axtens [Thu, 8 Mar 2018 01:28:22 +0000 (12:28 +1100)]
Fix slow Patch counting query
Stephen Rothwell noticed (way back in September - sorry Stephen!) that
the following query is really slow on OzLabs:
SELECT COUNT(*) AS "__count" FROM "patchwork_patch"
INNER JOIN "patchwork_submission" ON
("patchwork_patch"."submission_ptr_id" = "patchwork_submission"."id")
WHERE ("patchwork_submission"."project_id" = 14 AND
"patchwork_patch"."state_id" IN
(SELECT U0."id" AS Col1 FROM "patchwork_state" U0
WHERE U0."action_required" = true
ORDER BY U0."ordering" ASC));
I think this is really slow because we have to join the patch and
submission table to get the project id, which we need to filter the
patches.
Duplicate the project id in the patch table itself, which allows us to
avoid the JOIN.
The new query reads as:
SELECT COUNT(*) AS "__count" FROM "patchwork_patch"
WHERE ("patchwork_patch"."patch_project_id" = 1 AND
"patchwork_patch"."state_id" IN
(SELECT U0."id" AS Col1 FROM "patchwork_state" U0
WHERE U0."action_required" = true
ORDER BY U0."ordering" ASC));
Very simple testing on a small, artifical Postgres instance (3
projects, 102711 patches), shows speed gains of ~1.5-5x for this
query. Looking at Postgres' cost estimates (EXPLAIN) of the first
query vs the second query, we see a ~1.75x improvement there too.
I suspect the gains will be bigger on OzLabs.
Reported-by: Stephen Rothwell <sfr@canb.auug.org.au> Signed-off-by: Daniel Axtens <dja@axtens.net>