Сначала считаю сколько постов всего есть по тегам из таблицы tags_rel (id, id_tag, id_post) с проиндексированными колонками. ДАНО: юзер запрашивает посты с тегами, id которых равно 1, 2 или 3.
Берём только уникальные значения, конечно же, т.к. на каждый пост по несколько тегов, а значит могут повторяться посты, поэтому с GROUP BY:
SELECT COUNT(*)
FROM
(
SELECT tags_rel.id
FROM tags_rel
LEFT JOIN posts ON tags_rel.id_post = posts.id
WHERE id_tag IN (1,2,3) AND posts.status = 1
GROUP BY tags_rel.id_post
) t1
Всё, посчитали, здесь всё отлично, запрос обработан за 0.01сек.
Идём выковыривать теперь сами посты:
SELECT *
FROM
(
SELECT posts.*
FROM posts
LEFT JOIN tags_rel ON tags_rel.id_post = posts.id
WHERE id_tag IN (1,2,3) AND posts.status = 1
GROUP BY posts.id
) t1 LIMIT 0,50
И вот здесь всё хорошо ровно до тех пор, пока я не проставлю GROUP BY. Без группировки - сотые доли секунды. С группировкой - уже от 2 секунд и выше, в зависимости от количества найденного.
Как решать такие проблемы?
Думала уже может быстрее вообще все записи без пагинации вытащить, удалить как-то дубли из многомерного массива по колонке id и вытащить из него уже нужные для пагинации номера? Или память всю выжрет?
И сразу вдогонку вопрос может кто сталкиваться, если по FetchAll вытащить всё, как можно наиболее быстро сделать такой перебор многомерного массива на PHP? Можно ли так потягаться в производительности с SQL, или не стоит и пробовать?