Предположим, у вас есть такой запрос...
SELECT T.TaskID, T.TaskName, TAU.AssignedUsers
FROM `tasks` T
LEFT OUTER JOIN (
SELECT TaskID, GROUP_CONCAT(U.FirstName, ' ',
U.LastName SEPARATOR ', ') AS AssignedUsers
FROM `tasks_assigned_users` TAU
INNER JOIN `users` U ON (TAU.UserID=U.UserID)
GROUP BY TaskID
) TAU ON (T.TaskID=TAU.TaskID)
На одну задачу может быть назначено несколько человек. Цель этого запроса - показать одну строку для каждой задачи, но с людьми, назначенными на задачу, в одном столбце
Теперь... предположим, что у вас установлены соответствующие индексы на tasks
, users
и tasks_assigned_users
. Оптимизатор MySQL все равно не будет использовать индекс TaskID при присоединении tasks
к производной таблице. WTF?!?!???
Итак, мой вопрос... как можно заставить этот запрос использовать индекс на tasks_assigned_users.TaskID? Временные таблицы - отстой, так что если это единственное решение... оптимизатор MySQL тупит.
Используемые индексы:
EDIT: Также, на этой странице говорится, что производные таблицы выполняются/материализуются до возникновения объединений. Почему бы не использовать ключи повторно для выполнения соединения?
EDIT 2: MySQL Optimizer не позволит вам поставить индексные подсказки на производные таблицы (предположительно потому, что в производных таблицах нет индексов)
EDIT 3: Вот действительно хорошая запись в блоге об этом: http://venublog.com/2010/03/06/how-to-improve-subqueries-derived-tables-performance/ Обратите внимание, что случай #2 - это решение, которое я ищу, но похоже, что MySQL не поддерживает это в настоящее время. :(
EDIT 4: Только что нашел это: "Начиная с MySQL 5.6.3, оптимизатор более эффективно обрабатывает подзапросы в предложении FROM (то есть производные таблицы):... Во время выполнения запроса оптимизатор может добавить индекс к производной таблице, чтобы ускорить получение строк из нее." Кажется многообещающим...