Простой, но медленный запрос в Mysql, что соптимизить

Запрос примитивный — вытащить посты по указанному тегу

SELECT SQL_NO_CACHE posts.id, posts.text, posts.anno, posts.date
FROM `posts`
INNER JOIN `posts_xref_tags` ON posts_xref_tags.post_id = posts.id
WHERE posts_xref_tags.tag_id = 1
ORDER BY posts.date DESC
LIMIT 0,10

в posts primary на id, индекс на date

в posts_xref_tags составной primary на tag_id + post_id и индекс на tag_id

Постов в базе 30000, перекрестных связей 40000… постов имеющих связь с tag_id = 1 4,281

запрос выполняется за 0.2с

explain:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE posts_xref_tags ref PRIMARY,tag_id tag_id 4 const 4244 Using temporary; Using filesort
1 SIMPLE posts eq_ref PRIMARY PRIMARY 4 db_site. posts_xref_tags. post_id 1


UPD: Нашел решение!!!

SELECT SQL_NO_CACHE posts.id, posts.text, posts.anno, posts.create_date
FROM `az_posts`
WHERE id
IN (

SELECT `post_id`
FROM `posts_xref_tags`
WHERE tag_id =1
)
ORDER BY posts.create_date DESC
LIMIT 0, 10

выполняется за 0.002с
всем спасибо!
  • Вопрос задан
  • 2985 просмотров
Решения вопроса 1
DexizeR
@DexizeR Автор вопроса
Нашел решение!!!
SELECT SQL_NO_CACHE p.id, p.text, p.anno, p.create_date
FROM `az_posts` p
WHERE id
IN (

SELECT `post_id`
FROM az_posts_tags
WHERE tag_id =1
)
ORDER BY p.create_date DESC
LIMIT 0, 10

выполняется за 0.002с
всем спасибо!
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 4
@IlVin
SELECT p.id, p.text, p.anno, p.date
FROM `posts` p
INNER JOIN
( SELECT distinct `post_id`
FROM posts_xref_tags
WHERE tag_id = 1 ) AS pids ON (p.id=pids.post_id)
ORDER BY p.date DESC
LIMIT 0,10
Ответ написан
SCode
@SCode
P.S. Индексы — очень важная вещь. И продумывать их надо до конструирования таблицы.
Ответ написан
Комментировать
Сделайте двойной индекс на tag_id и date.
Ответ написан
@mitnlag
Без Order и Limit вероятнее всего не будет использоваться temprorary, что создает временную таблицу НА ДИСКЕ. Таким образом, нужно либо убрать SQL_NO_CACHE, чтобы воспользоваться нормальным механизмом, либо исключить создание файлов, убрав order и limit, либо поместить /tmp на SSD.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы