Rewrite CommitQuery to use UNION for performance

Summary:
Ref T12680. See PHI167. See that task for discussion.

Rewrite `DiffusionCommitQuery` to work more like `DifferentialRevisionQuery`, and use a UNION to find "all revisions you need to audit OR respond to".

I tried to get this working a little more cleanly than RevisionQuery does, and can probably simplify that now.

Test Plan: Poked at the UI locally without hitting any apparent issues, but my local data is pretty garbage at this point. I'll take a look at how the query plans work on `secure`.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T12680

Differential Revision: https://secure.phabricator.com/D18722
This commit is contained in:
epriestley
2017-10-20 15:37:19 -07:00
parent 63e6b2553e
commit 157f47cd14
2 changed files with 85 additions and 33 deletions

View File

@@ -111,7 +111,19 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery
AphrontDatabaseConnection $conn,
$table_name) {
$rows = queryfx_all(
$query = $this->buildStandardPageQuery($conn, $table_name);
$rows = queryfx_all($conn, '%Q', $query);
$rows = $this->didLoadRawRows($rows);
return $rows;
}
protected function buildStandardPageQuery(
AphrontDatabaseConnection $conn,
$table_name) {
return qsprintf(
$conn,
'%Q FROM %T %Q %Q %Q %Q %Q %Q %Q',
$this->buildSelectClause($conn),
@@ -123,10 +135,6 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery
$this->buildHavingClause($conn),
$this->buildOrderClause($conn),
$this->buildLimitClause($conn));
$rows = $this->didLoadRawRows($rows);
return $rows;
}
protected function didLoadRawRows(array $rows) {
@@ -1032,7 +1040,10 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery
/**
* @task order
*/
final protected function buildOrderClause(AphrontDatabaseConnection $conn) {
final protected function buildOrderClause(
AphrontDatabaseConnection $conn,
$for_union = false) {
$orderable = $this->getOrderableColumns();
$vector = $this->getOrderVector();
@@ -1045,7 +1056,7 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery
$parts[] = $part;
}
return $this->formatOrderClause($conn, $parts);
return $this->formatOrderClause($conn, $parts, $for_union);
}
@@ -1054,7 +1065,8 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery
*/
protected function formatOrderClause(
AphrontDatabaseConnection $conn,
array $parts) {
array $parts,
$for_union = false) {
$is_query_reversed = false;
if ($this->getBeforeID()) {
@@ -1075,6 +1087,13 @@ abstract class PhabricatorCursorPagedPolicyAwareQuery
}
$table = idx($part, 'table');
// When we're building an ORDER BY clause for a sequence of UNION
// statements, we can't refer to tables from the subqueries.
if ($for_union) {
$table = null;
}
$column = $part['column'];
if ($table !== null) {