Distribution:+bugtarget-portlet-bugfilters-stats timeouts
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Launchpad itself |
Fix Released
|
Critical
|
Robert Collins |
Bug Description
69 SELECT COUNT(*) FROM BugTask LEFT JOIN Bug ON BugTask.bug = Bug.id LEFT JOIN Product ON BugTask.p ... icipation.person = $INT AND TeamParticipati
13 https:/
OOPS-1857C157, OOPS-1857C1705, OOPS-1857C1709, OOPS-1857C1710, OOPS-1857E1397
10 https:/
OOPS-1857C252, OOPS-1857C719, OOPS-1857C816, OOPS-1857D247, OOPS-1857G651
SQL time: 14055 ms
Non-sql time: 125 ms
Total time: 14180 ms
Statement Count: 32
Three very slow queries:
1 5401.0 1 SQL-launchpad-
SELECT COUNT(*)
FROM BugTask
LEFT JOIN Bug ON BugTask.bug = Bug.id
LEFT JOIN Product ON BugTask.product = Product.id
LEFT JOIN SourcePackageName ON BugTask.
WHERE Bug.id = BugTask.bug
AND BugTask.
AND (BugTask.status = 10)
AND Bug.duplicateof IS NULL
AND (Bug.private = FALSE
OR EXISTS
(SELECT BugSubscription.bug
FROM BugSubscription,
WHERE TeamParticipati
AND TeamParticipati
AND BugSubscription.bug = Bug.id
UNION SELECT BugTask.bug
FROM BugTask,
WHERE TeamParticipati
AND TeamParticipati
AND BugTask.bug = Bug.id))
2 4675.0 1 SQL-launchpad-
SELECT COUNT(*)
FROM BugTask
LEFT JOIN Bug ON BugTask.bug = Bug.id
LEFT JOIN Product ON BugTask.product = Product.id
LEFT JOIN SourcePackageName ON BugTask.
WHERE Bug.id = BugTask.bug
AND BugTask.
AND ((BugTask.status = 10)
OR (BugTask.status = 15)
OR (BugTask.status = 20)
OR (BugTask.status = 21)
OR (BugTask.status = 22)
OR (BugTask.status = 25))
AND Bug.duplicateof IS NULL
AND (Bug.private = FALSE
OR EXISTS
(SELECT BugSubscription.bug
FROM BugSubscription,
WHERE TeamParticipati
AND TeamParticipati
AND BugSubscription.bug = Bug.id
UNION SELECT BugTask.bug
FROM BugTask,
WHERE TeamParticipati
AND TeamParticipati
AND BugTask.bug = Bug.id))
3 2703.0 1 SQL-launchpad-
SELECT COUNT(*)
FROM BugTask
LEFT JOIN Bug ON BugTask.bug = Bug.id
LEFT JOIN Product ON BugTask.product = Product.id
LEFT JOIN SourcePackageName ON BugTask.
WHERE Bug.id = BugTask.bug
AND BugTask.
AND ((BugTask.status = 10)
OR (BugTask.status = 15)
OR (BugTask.status = 20)
OR (BugTask.status = 21)
OR (BugTask.status = 22)
OR (BugTask.status = 25))
AND Bug.duplicateof IS NULL
AND Bug.latest_
AND (Bug.private = FALSE
OR EXISTS
(SELECT BugSubscription.bug
FROM BugSubscription,
WHERE TeamParticipati
AND TeamParticipati
AND BugSubscription.bug = Bug.id
UNION SELECT BugTask.bug
FROM BugTask,
WHERE TeamParticipati
AND TeamParticipati
AND BugTask.bug = Bug.id))
We can perhaps only show public stats all the time, or do two queries for pub/private. DBA recommendations solicited.
Related branches
- Abel Deuring (community): Approve (code)
-
Diff: 460 lines (+137/-79)6 files modifiedlib/lp/bugs/browser/bugtask.py (+69/-12)
lib/lp/bugs/browser/tests/special/bugs-fixed-elsewhere.txt (+19/-21)
lib/lp/bugs/browser/tests/test_bugtarget_patches_view.py (+9/-38)
lib/lp/bugs/configure.zcml (+5/-0)
lib/lp/bugs/interfaces/bugtask.py (+23/-1)
lib/lp/bugs/model/bugtask.py (+12/-7)
description: | updated |
tags: | added: dba |
Changed in launchpad: | |
assignee: | nobody → Robert Collins (lifeless) |
tags: | removed: dba |
Changed in launchpad: | |
status: | Fix Committed → Fix Released |
SourcepackageName and Product are an unnecessary joins for the COUNT queries. I suspect this is coming from prejoins, and we would benefit by removing them and doing two separate queries for the sourcepackagenames and products if they are needed.
The private flag has always caused bad queries. One option for tackling this problem is to do two queries - one for private, one for public (either client side or aggregating two subqueries queries server side). We can then create partial indexes on the column being used for the join (eg. CREATE UNIQUE INDEX bug__id_ _private_ _key ON Bug(id) WHERE private IS TRUE and CREATE INDEX bug__id_ _public_ _key ON Bug(id) WHERE private IS FALSE. We would have to test what columns would use the partial index - product, distribution, sourcepackagename and id are all candidates.
One thing that can be confusing the planner is using = for boolean comparisons. Bug.private = FALSE is different to Bug.private IS FALSE due to SQL's three value logic, and in particular, using = would cause the partial indexes I described to not be used.
distribution == 1 is also always an issue. We might consider duplicating existing indexes as partial indexes 'WHERE distribution = 1', because we know Ubuntu is a special case and will remain so. eg. CREATE INDEX bugtask_ _status_ _ubuntu_ _idx ON BugTask(status) WHERE distribution = 1.
Of course, doing a query for 'all open Ubuntu Bugs' is going to be slow because this is a lot of bugs. However, people need counts of bugs in various statuses for their projects. We should consider breaking out these counts into a table for public bugs. eg.
CREATE TABLE BugTaskStatusCount ( gename REFERENCES SourcepackageName,
id serial PRIMARY KEY,
product integer REFERENCES Product,
distribution integer REFERENCES Distribution,
sourcepacka
status integer NOT NULL,
count integer NOT NULL
);
The table would need to be maintained of course - triggers, python code in the model objects, a cronscript, whatever.
The table would be queried for public bug counts. Private bug counts would be done live, and since private bugs are a minority we can create partial indexes to make the queries fast.