У меня есть большой запрос MySQL, который фактически возвращает хороший набор результатов, но он довольно медленный.Как улучшить список моих друзей MySQL?
SELECT DISTINCT
username,
user.id as uid,
email,
ui.gender,
ui.country,
ui.birthday,
IF(last_activity_date >= now() - INTERVAL 1 HOUR, 1, 0) as is_online,
p.thumb_url,
friend_request.id as sr_id,
IF(ul.id IS NOT NULL, 1, 0) as st_love,
DATE_FORMAT(NOW(), '%Y') - DATE_FORMAT(birthday, '%Y') - (DATE_FORMAT(NOW(), '00-%m-%d') < DATE_FORMAT(birthday, '00-%m-%d')) AS age
FROM friend_request
JOIN user ON (user.`id` = friend_request.`to_user_id`
OR
user.`id` = friend_request.`from_user_id`)
AND user.`id` != '$user_id'
AND friend_request.`status` = '1'
JOIN user_info ui ON user.`id` = ui.`user_id`
JOIN photo p ON ui.`main_photo` = p.`id`
LEFT JOIN user_love ul ON ul.`to_user_id` = user.`id`
AND ul.`from_user_id` = $user_id
WHERE (friend_request.`to_user_id` = '$user_id'
OR friend_request.`from_user_id` = '$user_id')
ORDER BY friend_request.id DESC
LIMIT 30
"$ user_id" является идентификатором зарегистрированного пользователя.
Вот структуру таблиц «friend_request»:
CREATE TABLE `friend_request` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`from_user_id` int(11) DEFAULT NULL,
`to_user_id` int(11) DEFAULT NULL,
`date` datetime DEFAULT NULL,
`seen` int(11) DEFAULT '0',
`status` int(11) DEFAULT '0',
PRIMARY KEY (`id`),
KEY `from_user_id` (`from_user_id`),
KEY `to_user_id` (`to_user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
Можете ли вы помочь мне улучшить этот запрос?
Я не скопировал структуру таблицы других таблиц, потому что после некоторых тестов «проблема оптимизации», похоже, поступает из таблицы friend_request.
Спасибо!
EDIT:
Вот что "EXPLAIN" дает мне:
Рассмотрите возможность предоставления набора данных и желаемого набора результатов. – Strawberry
В ЛЮБОМ СОЕДИНЕНИИ, а не ВПРАВО. (Конечно, вы должны переключить таблицы слева <-> справа тоже ...) Это реальное улучшение удобочитаемости! (У большинства людей достаточно проблем с левым соединением и слишком запутаны, когда дело доходит до правильного соединения ...) – jarlh
Вы называете это из приложения? Возможно, вы можете сделать некоторую бизнес-логику (все операторы if/then и преобразования даты) в своем коде приложения и передать параметризованный список на MySql, чтобы облегчить часть обработки в базе данных. И я согласен с @jarlh использовать левые соединения вместо правого. – ragerory