MYSQL: ВЫБОР пользователей из одной группы пользователей и исключение пользователей из другой группы - оптимизация - PullRequest
1 голос
/ 23 марта 2011

У меня есть вопрос по оптимизации здесь.

Фон

У меня 12000 пользователей в пользовательской таблице, по записи на пользователя. Каждый пользователь может быть в нуле или более групп. У меня есть таблица групп с 45 группами и таблица groups_link с 75000 записями (чтобы облегчить отношения многие ко многим).

Я делаю экран запросов, который позволяет пользователю отфильтровывать пользователей из списка пользователей.

Aim

В частности, мне нужна помощь: Выбор всех пользователей, которые входят в одну группу, но не находятся в другой группе.

Структура БД

enter image description here

Запрос

Мой текущий запрос, который выполняется слишком медленно ...

 SELECT U.user_id,U.user_email
FROM (sc_module_users AS U)
JOIN sc_module_users_groups_links AS group_join ON group_join.user_id = U.user_id
LEFT JOIN sc_module_users_groups_links AS excluded_group_join ON group_join.user_id = U.user_id
WHERE group_join.group_id IN (27) AND excluded_group_join.group_id NOT IN (19) OR excluded_group_join.group_id IS NULL AND U.user_subscribed=1 AND U.user_active=1
GROUP BY U.user_id,U.user_id

Этот запрос занимает 9 минут, он возвращает 11 000 записей (из 12 000).

Объясните

Вот объяснение этого запроса: enter image description here Нажмите здесь, чтобы ближе посмотреть

Может кто-нибудь помочь мне оптимизировать это до отметки ниже 1 минуты ...?

После 3 ревизий я изменил это на

    SELECT U.user_id,U.user_email FROM (sc_module_users AS U) WHERE ( user_country LIKE '%australia%' ) AND 
EXISTS (SELECT group_id FROM sc_module_users_groups_links l WHERE group_id in (31) AND l.user_id=U.user_id) AND 
NOT EXISTS (SELECT group_id FROM sc_module_users_groups_links l WHERE group_id in (27) AND l.user_id=U.user_id) 
AND U.user_subscribed=1 AND U.user_active=1 GROUP BY U.user_id

намного быстрее

Ответы [ 2 ]

1 голос
/ 23 марта 2011

РЕДАКТИРОВАТЬ: удалил мое предложение запроса, но индекс все равно должен применяться:

Индексы на sc_module_users_groups_links можно улучшить, создав составной индекс только на user_id и group_id.Порядок столбцов в индексе может оказать влияние - я считаю, что сначала нужно иметь user_id.

Вы также можете попробовать удалить link_id и просто использовать составной первичный ключ, начиная с * 1010.* похоже, не служит никаким другим целям.

0 голосов
/ 23 марта 2011

Я считаю, что самое первое, что вам нужно сделать, это поставить круглые скобки:

// should be  
.. AND ( excluded_group_join.group_id NOT IN (19) 
  OR excluded_group_join.group_id IS NULL)  AND ....
...