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:
@@ -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) {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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}'!");
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user