Медленный MySQL из PHP Board

У меня есть несколько таблиц php-доски.

Мне нужен эффективный запрос, чтобы выбрать все категории, все темы, последнее сообщение из тем, с опубликованным пользователем. По моему запросу на его выполнение уходит 5-8 секунд.
Я выполнил оптимизацию с помощью поля last_post_id в таблице тем, но мне нужно лучшее решение для него.

Состав

forum_categories ~ 15 lines
id|name|...

forum_topics ~ 150 lines
id|name|category_id|...

forum_posts ~ 1.000.000 lines
id|body|topic_id|user_id|...

users ~ 30.000 lines
id|username|...category 1
- topic 1
- last post1 | user1
- topic 2
- last post2 | user2
...
category 2
- topic 3
- last post3 | user3
...
...

Последний запрос (Это была помощь моего друга. Но это также было так медленно.)

SELECT c.NAME     AS category,
t.NAME     AS topic,
p.body     AS post,
p.username AS username
FROM   forum_categories AS c
JOIN forum_topics AS t
ON t.category_id = c.id
JOIN (SELECT *
FROM   (SELECT p.body,
p.topic_id,
u.username
FROM   forum_posts AS p
JOIN users AS u
ON u.id = p.user_id
ORDER  BY p.id DESC) AS t
GROUP  BY topic_id) AS p
ON t.id = p.topic_id

Объясните запрос

PMA объяснить запрос

Статистика запроса

Заголовки: сортировка, статус, время | статус, все время, pct. время, звонки, время
статистика

4

Решение

Я думаю «последний пост из тем» является ключевой точкой вашего запроса. Вот почему вы использовали ORDER BY на большинстве внутренних запросов, но это делает два подзапроса.

Обновленная версия

CREATE TEMPORARY TABLE last_post_per_topic_t ENGINE = MEMORY
SELECT topic_id, MAX(id) AS id -----+
FROM forum_posts                    --> find last post id per topic
GROUP BY topic_id; -----------------+

ALTER TABLE last_post_per_topic_t ADD INDEX (id, topic_id);

SELECT *
FROM forum_categories AS c INNER JOIN forum_topics t ON c.id = t.category_id
INNER JOIN forum_posts p ON p.topic_id = t.id
INNER JOIN last_post_per_topic_t ON last_post_per_topic_t.topic_id = t.id
AND last_post_per_topic_t.id = p.id;
INNER JOIN users u ON p.user_id = u.id;

первая версия

SELECT *
FROM forum_categories AS c INNER JOIN forum_topics t ON c.id = t.category_id
INNER JOIN forum_posts p ON p.topic_id = t.id
INNER JOIN (
SELECT topic_id, MAX(id) AS id -----+
FROM forum_posts                    --- find last post_id per topic
GROUP BY topic_id    ---------------+
) last_post_per_topic_t ON last_post_per_topic_t.topic_id = t.id
AND last_post_per_topic_t.id = p.id;
1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]