From 0edce619c8822d3051886ee1b501d5f153e162a7 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 22 Apr 2022 13:31:34 +0200 Subject: [PATCH] tell mysql to ignore the sort index for search queries Signed-off-by: Robin Appelman --- lib/private/DB/QueryBuilder/QueryBuilder.php | 2 +- lib/private/Files/Cache/SearchBuilder.php | 11 +++++++++++ lib/public/DB/QueryBuilder/IQueryBuilder.php | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/private/DB/QueryBuilder/QueryBuilder.php b/lib/private/DB/QueryBuilder/QueryBuilder.php index 89265c74fae3e..bf5ec2f6bec91 100644 --- a/lib/private/DB/QueryBuilder/QueryBuilder.php +++ b/lib/private/DB/QueryBuilder/QueryBuilder.php @@ -1119,7 +1119,7 @@ public function orderBy($sort, $order = null) { /** * Adds an ordering to the query results. * - * @param string $sort The ordering expression. + * @param string|ILiteral|IParameter|IQueryFunction $sort The ordering expression. * @param string $order The ordering direction. * * @return $this This QueryBuilder instance. diff --git a/lib/private/Files/Cache/SearchBuilder.php b/lib/private/Files/Cache/SearchBuilder.php index 003d3ac15e776..c8c442bcb8cd8 100644 --- a/lib/private/Files/Cache/SearchBuilder.php +++ b/lib/private/Files/Cache/SearchBuilder.php @@ -232,6 +232,17 @@ public function addSearchOrdersToQuery(IQueryBuilder $query, array $orders) { if ($field === 'fileid') { $field = 'file.fileid'; } + + // Mysql really likes to pick an index for sorting if it can't fully satisfy the where + // filter with an index, since search queries pretty much never are fully filtered by index + // mysql often picks an index for sorting instead of the much more useful index for filtering. + // + // By changing the order by to an expression, mysql isn't smart enough to see that it could still + // use the index, so it instead picks an index for the filtering + if ($field === 'mtime') { + $field = $query->func()->add($field, $query->createNamedParameter(0)); + } + $query->addOrderBy($field, $order->getDirection()); } } diff --git a/lib/public/DB/QueryBuilder/IQueryBuilder.php b/lib/public/DB/QueryBuilder/IQueryBuilder.php index 7829696970cdb..c4167b2175f48 100644 --- a/lib/public/DB/QueryBuilder/IQueryBuilder.php +++ b/lib/public/DB/QueryBuilder/IQueryBuilder.php @@ -824,7 +824,7 @@ public function orderBy($sort, $order = null); /** * Adds an ordering to the query results. * - * @param string $sort The ordering expression. + * @param string|ILiteral|IParameter|IQueryFunction $sort The ordering expression. * @param string $order The ordering direction. * * @return $this This QueryBuilder instance.