1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-10 08:52:39 +01:00

Use (a = ? AND b = ?) instead of (a, b) IN (?, ?)

Summary: MySQL is not able to use indexes with searching for tuples.

Test Plan:
Explained the query before and after, saw `key_len` 16 instead of 8.
Also saw time 0.0 s instead of 2.9 s (but that was probably caused by warming up).

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Korvin

Differential Revision: https://secure.phabricator.com/D5580
This commit is contained in:
Jakub Vrana 2013-04-05 23:02:06 -07:00
parent 8716b295e7
commit 3391e3d34b
4 changed files with 15 additions and 9 deletions

View file

@ -102,7 +102,9 @@ final class DiffusionSvnBrowseQuery extends DiffusionBrowseQuery {
$sql = array(); $sql = array();
foreach ($index as $row) { foreach ($index as $row) {
$sql[] = '('.(int)$row['pathID'].', '.(int)$row['maxCommit'].')'; $sql[] =
'(pathID = '.(int)$row['pathID'].' AND '.
'svnCommit = '.(int)$row['maxCommit'].')';
} }
$browse = queryfx_all( $browse = queryfx_all(
@ -112,13 +114,13 @@ final class DiffusionSvnBrowseQuery extends DiffusionBrowseQuery {
WHERE repositoryID = %d WHERE repositoryID = %d
AND parentID = %d AND parentID = %d
AND existed = 1 AND existed = 1
AND (pathID, svnCommit) in (%Q) AND (%Q)
ORDER BY pathName', ORDER BY pathName',
PhabricatorRepository::TABLE_FILESYSTEM, PhabricatorRepository::TABLE_FILESYSTEM,
PhabricatorRepository::TABLE_PATH, PhabricatorRepository::TABLE_PATH,
$repository->getID(), $repository->getID(),
$path_id, $path_id,
implode(', ', $sql)); implode(' OR ', $sql));
$loadable_commits = array(); $loadable_commits = array();
foreach ($browse as $key => $file) { foreach ($browse as $key => $file) {

View file

@ -96,6 +96,10 @@ Create all indexes necessary for fast query execution in most cases. Don't
create indexes which are not used. You can analyze queries @{article:Using create indexes which are not used. You can analyze queries @{article:Using
DarkConsole}. DarkConsole}.
Older MySQL versions are not able to use indexes for tuple search:
`(a, b) IN ((%s, %d), (%s, %d))`. Use `AND` and `OR` instead:
`((a = %s AND b = %d) OR (a = %s AND b = %d))`.
= Foreign Keys = = Foreign Keys =
We don't use InnoDB's foreign keys because our application is so great that We don't use InnoDB's foreign keys because our application is so great that

View file

@ -171,14 +171,14 @@ final class PhabricatorWorkerLeaseQuery extends PhabricatorQuery {
foreach ($rows as $row) { foreach ($rows as $row) {
$in[] = qsprintf( $in[] = qsprintf(
$conn_w, $conn_w,
'(%d, %s)', '(id = %d AND leaseOwner = %s)',
$row['id'], $row['id'],
$row['leaseOwner']); $row['leaseOwner']);
} }
$where[] = qsprintf( $where[] = qsprintf(
$conn_w, $conn_w,
'(id, leaseOwner) IN (%Q)', '(%Q)',
'('.implode(', ', $in).')'); implode(' OR ', $in));
break; break;
default: default:
throw new Exception("Unknown phase '{$phase}'!"); throw new Exception("Unknown phase '{$phase}'!");

View file

@ -306,7 +306,7 @@ final class PhabricatorEdgeEditor extends PhabricatorEditor {
foreach ($edges as $edge) { foreach ($edges as $edge) {
$sql[] = qsprintf( $sql[] = qsprintf(
$conn_w, $conn_w,
'(%s, %d, %s)', '(src = %s AND type = %d AND dst = %s)',
$edge['src'], $edge['src'],
$edge['type'], $edge['type'],
$edge['dst']); $edge['dst']);
@ -323,9 +323,9 @@ final class PhabricatorEdgeEditor extends PhabricatorEditor {
foreach (array_chunk($sql, 256) as $chunk) { foreach (array_chunk($sql, 256) as $chunk) {
queryfx( queryfx(
$conn_w, $conn_w,
'DELETE FROM %T WHERE (src, type, dst) IN (%Q)', 'DELETE FROM %T WHERE (%Q)',
PhabricatorEdgeConfig::TABLE_NAME_EDGE, PhabricatorEdgeConfig::TABLE_NAME_EDGE,
implode(', ', $chunk)); implode(' OR ', $chunk));
} }
} }
} }