Очень медленный mysql запрос из за ORDER BY
Есть таблица с комментариями (более 5миллионов записей)
CREATE TABLE `topic_comment` (
`topic_id` INT(11) UNSIGNED NULL DEFAULT NULL,
`user_id` INT(11) NULL DEFAULT NULL,
`comment_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`comment_text` TEXT NULL DEFAULT NULL COLLATE 'utf8_general_ci',
`comment_timestamp` INT(11) UNSIGNED NULL DEFAULT NULL,
`comment_activity` TINYINT(1) NULL DEFAULT '1',
`rate_pl` INT(11) UNSIGNED NOT NULL DEFAULT '0',
`rate_mi` INT(11) UNSIGNED NOT NULL DEFAULT '0',
PRIMARY KEY (`comment_id`) USING BTREE,
INDEX `user_id` (`user_id`) USING BTREE,
INDEX `topic_id` (`topic_id`) USING BTREE,
INDEX `comment_activity` (`comment_activity`) USING BTREE,
INDEX `comment_timestamp` (`comment_timestamp`) USING BTREE
)
COLLATE='utf8_general_ci'
ENGINE=MyISAM
AUTO_INCREMENT=5528579;
Таблица пользователей (это не столь важно)
CREATE TABLE `user` (
`user_id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`user_email` VARCHAR(60) NULL DEFAULT NULL COLLATE 'utf8_general_ci',
PRIMARY KEY (`user_id`) USING BTREE,
UNIQUE INDEX `user_email` (`user_email`) USING BTREE
)
COLLATE='utf8_general_ci'
ENGINE=MyISAM
AUTO_INCREMENT=216013;
Есть запрос который из за ORDER BY очень медленный!
SELECT tc.*, u.user_email
FROM topic_comment tc
left JOIN user u ON u.user_id = tc.user_id
WHERE tc.topic_id = '45712'
ORDER BY tc.comment_id
LIMIT 6, 15
Вот как проверяю время выполнения
$prevTime = microtime(true);
после запроса
$curTime = microtime(true);
ECHO $diffTime = round($curTime - $prevTime, 2);
А вот результат на достаточно не плохом железе 11.67!
Если убрать сортировку запрос срабатывает очень быстро, но, к сожалению, последовательность нарушена!
Буду признателен за совет!
Ответы (1 шт):
Автор решения: Akina
→ Ссылка
Если ориентироваться на смысл, то
SELECT *
FROM ( SELECT *
FROM topic_comment tc
WHERE tc.topic_id = '45712'
ORDER BY tc.comment_id
LIMIT 6, 15 ) subq
JOIN user u ON u.user_id = subq.user_id
Но отсутствие схемы и отсутствие внешних ключей в показанной структуре допускает любой [censored] - так что проверяй, соответствует ли это требуемой логике.
Дополнительно.
- Прибить индекс по topic_id, а вместо него создать композитный по
(topic_id, comment_id) - Хорошенько подумать, нужны ли ВСЕ поля. Заменить звёзды на список реально необходимых полей.
- В соответствии с п. 2 пересмотреть индекс, создаваемый по п. 1.