Colin Watson has proposed merging 
~cjwatson/launchpad:optimize-specification-search into launchpad:master.

Commit message:
Fix query plan for specification searches

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)
Related bugs:
  Bug #1995686 in Launchpad itself: "openstack-neutron launchpad start page 
timeout"
  https://bugs.launchpad.net/launchpad/+bug/1995686

For more details, see:
https://code.launchpad.net/~cjwatson/launchpad/+git/launchpad/+merge/435749

When given base clauses, `search_specifications` is intended to assume that 
those are more selective than other criteria: for example, starting by 
filtering specifications by project is likely to cut down the row count a lot 
more than filtering by status.  However, it constructed a query of the form:

    WITH RelevantSpecification AS (...)
    SELECT Specification.*
    FROM Specification
    WHERE
        Specification.id IN (
            SELECT RelevantSpecification.id FROM RelevantSpecification
        )
        AND ...;

This caused the PostgreSQL planner to find relevant specifications using the 
base clauses, then filter all specifications according to the other clauses, 
then join the results of those two searches together: the worst of both worlds. 
 Instead, we want a query of the form:

    WITH RelevantSpecification AS (...)
    SELECT Specification.*
    FROM
        Specification
        JOIN RelevantSpecification
             ON Specification.id = RelevantSpecification.id
    WHERE ...;

This results in a query plan that finds relevant specifications using the base 
clauses and then filters the result of that search using the other clauses.  
Much more sensible, and takes milliseconds rather than seconds.
-- 
Your team Launchpad code reviewers is requested to review the proposed merge of 
~cjwatson/launchpad:optimize-specification-search into launchpad:master.
diff --git a/lib/lp/blueprints/model/specificationsearch.py b/lib/lp/blueprints/model/specificationsearch.py
index f505628..243e4c9 100644
--- a/lib/lp/blueprints/model/specificationsearch.py
+++ b/lib/lp/blueprints/model/specificationsearch.py
@@ -111,12 +111,14 @@ def search_specifications(
             Select(Specification.id, And(clauses), tables=tables),
         )
         store = store.with_(relevant_specification_cte)
-        tables = [Specification]
-        clauses = [
-            Specification.id.is_in(
-                Select(Column("id", RelevantSpecification))
+        tables = [
+            Specification,
+            Join(
+                RelevantSpecification,
+                Specification.id == Column("id", RelevantSpecification),
             ),
         ]
+        clauses = []
     clauses.extend(get_specification_privacy_filter(user))
     clauses.extend(get_specification_filters(spec_filter))
 
_______________________________________________
Mailing list: https://launchpad.net/~launchpad-reviewers
Post to     : launchpad-reviewers@lists.launchpad.net
Unsubscribe : https://launchpad.net/~launchpad-reviewers
More help   : https://help.launchpad.net/ListHelp

Reply via email to