Здравствуйте. Как можно оптимизировать такой MySQL-запрос? Код (Text): SELECT U.id,U.name,U.birthday,U.sex,U.city,U.status,U.regdate FROM users U LEFT JOIN shipping SA ON SA.user_id=U.id LEFT JOIN activity A ON A.user_id=U.id LEFT JOIN blocked B ON B.user_id=U.id LEFT JOIN deleted D ON D.user_id=U.id WHERE SA.id and A.last_activity_at > 1553260577 and B.id is NULL and D.id is NULL and U.id NOT IN ( ( SELECT who_id FROM blacklist WHERE user_id=17 ) UNION ( SELECT user_id FROM blacklist WHERE who_id=17 ) UNION ( SELECT 17 ) ) GROUP BY U.id ORDER BY U.id DESC LIMIT 1 OFFSET 3
1. разумная денормализация: создать логическое поле inactive в users, которое будет 1 в случае попадания пользователя в blocked или deleted. в таком случае можно избавиться от двух джойнов. 2. я так понимаю blacklist это персональный черный список: если я не хочу дружить с Петей или Петя не хочет дружить со мной. такие вещи можно кешировать для текущего пользователя и подставлять в запрос готовый список айдишников как NOT IN (готовый_список_ids_как_параметр) таким образом запрос будет без джойнов и подзапросов вообще. group by u.id мне кажется здесь просто лишний. да и ошибка это при строгом ansi sql. limit 1 без сортировки, это точно ???
PHP: SELECT U.id, U.name, U.birthday, U.sex, U.city, U.status, U.regdate FROM users U INNER JOIN shipping SA ON SA.user_id=U.id INNER JOIN activity A ON A.user_id=U.id LEFT JOIN blocked B ON B.user_id=U.id LEFT JOIN deleted D ON D.user_id=U.id WHERE A.last_activity_at > 1553260577 and B.id is NULL and D.id is NULL AND U.id NOT IN ( SELECT IF(user_id=17, who_id, IF(who_id=17, user_id, 0)) FROM blacklist WHERE user_id=17 OR who_id=17 UNION SELECT 17 ) ORDER BY U.id DESC LIMIT 1 OFFSET 3; Если миллионы записей в Blacklist, то вместо NOT IN() можно попробовать выборку нужных ИД во временную таблицу, и потом джойн с ней.