Я переписываю SQL, который позволяет пользователю искать любого другого пользователя на нашем сайте, а также показывает его роли.
В качестве примера, ролями могут быть «Автор», «Редактор», «Издатель».
Каждая роль связывает пользователя с публикацией.
Пользователи могут выполнять несколько ролей в нескольких публикациях.
Пример настройки таблицы:
"users" : user_id, firstname, lastname
"publications" : publication_id, name
"link_writers" : user_id, publication_id
"link_editors" : user_id, publication_id
Текущий псевдо-SQL:
SELECT * FROM (
(SELECT user_id FROM users WHERE firstname LIKE '%Jenkz%')
UNION
(SELECT user_id FROM users WHERE lastname LIKE '%Jenkz%')
) AS dt
JOIN (ROLES STATEMENT) AS roles ON roles.user_id = dt.user_id
На данный момент мои роли:
SELECT dt2.user_id, dt2.publication_id, dt.role FROM (
(SELECT 'writer' AS role, link_writers.user_id, link_writers.publication_id
FROM link_writers)
UNION
(SELECT 'editor' AS role, link_editors.user_id, link_editors.publication_id
FROM link_editors)
) AS dt2
Причина переноса оператора ролей в предложениях UNION заключается в том, что некоторые роли являются более сложными и требуют объединения таблиц для поиска идентификатора публикации и идентификатора пользователя.
В качестве примера "издатели" могут быть связаны между двумя таблицами
"link_publishers": user_id, publisher_group_id
"link_publisher_groups": publisher_group_id, publication_id
Таким образом, в этом случае запрос, формирующий часть моего UNION, будет:
SELECT 'publisher' AS role, link_publishers.user_id, link_publisher_groups.publication_id
FROM link_publishers
JOIN link_publisher_groups ON lpg.group_id = lp.group_id
Я довольно уверен, что мои настройки таблицы хороши (меня предупредили о системе «одна таблица для всех» при исследовании макета). Моя проблема в том, что в таблице пользователей теперь 100 000 строк и до 70 000 строк в каждой из таблиц ссылок.
Первоначальный поиск в таблице пользователей выполняется быстро, но объединение действительно замедляет работу.
Как я могу присоединиться только к соответствующим ролям?
-------------------------- РЕДАКТИРОВАТЬ -------------------- --------------
Объясните выше (откройте в новом окне, чтобы увидеть полное разрешение).
Нижний бит красного цвета - это "WHERE firstname LIKE"% Jenkz% "", в третьей строке выполняется поиск WHERE CONCAT (имя, '', фамилия) LIKE "% Jenkz%". Отсюда большое количество строк, но я думаю, что это неизбежно, если только нет способа поместить индекс в объединенные поля?
Зеленый бит вверху показывает общее количество строк, отсканированных из ЗАЯВЛЕНИЯ О РОЛЯХ.
Затем вы можете увидеть каждое отдельное предложение UNION (# 6 - # 12), которое показывает большое количество строк. Некоторые индексы нормальные, некоторые уникальные.
Кажется, что MySQL не оптимизирует использование dt.user_id для сравнения внутренних операторов UNION. Есть ли способ заставить это поведение?
Обратите внимание, что мои настоящие настройки - это не публикации и не писатели, а "веб-мастера", "игроки", "команды" и т. Д.