From 6c932cf98cce554a73a77ae218fb15cf6114566d Mon Sep 17 00:00:00 2001 From: Go MAEDA Date: Sat, 10 Jan 2026 01:58:32 +0000 Subject: [PATCH] Add a MySQL optimizer hint to fix a performance regression introduced in r23979 when searching issues with custom fields (#43651). Patch by Go MAEDA (user:maeda). git-svn-id: https://svn.redmine.org/redmine/trunk@24289 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- .../lib/acts_as_searchable.rb | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb b/lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb index d393285b0..fd7a11707 100644 --- a/lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb +++ b/lib/plugins/acts_as_searchable/lib/acts_as_searchable.rb @@ -109,13 +109,20 @@ module Redmine clauses << "(#{CustomValue.table_name}.custom_field_id IN (#{fields.map(&:id).join(',')}) AND (#{visibility}))" end visibility = clauses.join(' OR ') - r |= fetch_ranks_and_ids( - search_scope(user, projects, options). - joins(:custom_values). - where(visibility). - where(search_tokens_condition(["#{CustomValue.table_name}.value"], tokens, options[:all_words])), - options[:limit] - ) + scope = + search_scope(user, projects, options) + .joins(:custom_values) + .where(visibility) + .where(search_tokens_condition(["#{CustomValue.table_name}.value"], tokens, options[:all_words])) + + if self == Issue && Redmine::Database.mysql? && ActiveRecord::Base.connection.supports_optimizer_hints? + # Force the join order to evaluate issues before custom_values. + # This avoids inefficient query plans where custom_values are scanned + # without an issue_id filter, which can be extremely slow on large datasets. + scope = scope.optimizer_hints("JOIN_ORDER(#{Issue.table_name}, #{CustomValue.table_name})") + end + + r |= fetch_ranks_and_ids(scope, options[:limit]) queries += 1 end end