Сведения о вопросе

Holish

21:06, 1st October, 2020

Теги

MySQL    

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

Просмотров: 210   Ответов: 5

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

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с
всем спасибо!



  Сведения об ответе

LIZA

00:19, 26th September, 2020

Нашел решение!!!
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с
всем спасибо!


  Сведения об ответе

+-*/

00:54, 26th September, 2020

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


  Сведения об ответе

KOMP

11:01, 27th September, 2020

P.S. Индексы — очень важная вещь. И продумывать их надо до конструирования таблицы.


  Сведения об ответе

SILA

12:17, 28th September, 2020

Сделайте двойной индекс на tag_id и date.


  Сведения об ответе

SSESION

15:26, 28th September, 2020

Без Order и Limit вероятнее всего не будет использоваться temprorary, что создает временную таблицу НА ДИСКЕ. Таким образом, нужно либо убрать SQL_NO_CACHE, чтобы воспользоваться нормальным механизмом, либо исключить создание файлов, убрав order и limit, либо поместить /tmp на SSD.


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться