aprenoir
@aprenoir
программный архитектор

Как правильно составить SQL запрос?

Привет всем!

Как составить наиболее производительный запрос к БД (MySQL, InnoDB) в следующей ситуации. Имеется таблица USER_POSTS, где хранятся данные о постах пользователей. В таблице порядка 20 млн. записей о постах пользователей, размер 20Gb, у каждого пользователя в среднем 3000 постов (данные собираются из других социальных сетей). Требуется выводить по 20 записей на страницу, отбираемых по OWNER_ID (владелец профиля) и сортируемых по CREATED (дате создания). По OWNER_ID и CREATED выставлены индексы.

Наиболее простое решение в моем случае будет следующим:

SELECT post_id, owner_id, content_text, location_name, provider_id, provider_source_id, provider_source_id_full, provider_source_domain, provider_source_link, provider_source_name, provider_source_photo, provider_post_link, attachment_0_photo, created
FROM user_posts
WHERE owner_id='30'
ORDER BY created DESC
LIMIT 20;


Проблема в том, что до попадания этого запроса в кэш MySQL, время его выполнения для меня неприемлемо. Пробовал такой вариант:

SELECT b.post_id, b.owner_id, b.content_text, b.location_name, b.provider_id, b.provider_source_id, b.provider_source_id_full, b.provider_source_domain, b.provider_source_link, b.provider_source_name, b.provider_source_photo, b.provider_post_link, b.attachment_0_photo, b.created
FROM (
   SELECT post_id
   FROM user_posts
   WHERE owner_id='30'
   ORDER BY created DESC
   LIMIT 20
) a, user_posts b
WHERE b.post_id=a.post_id;


Выдает более производительный результат, но все равно достаточно медленно. Как я понял, узким местом является сортировка по полю CREATED. Без нее запрос идет в 5-7 раз быстрее, но ее нельзя убрать. Посты по индексу POST_ID идут не в хронологическом порядке.

Как можно составить более быстрый запрос на основе этих исходных данных? Что еще можно сделать для более производительного выполнения запросов такого типа?
  • Вопрос задан
  • 290 просмотров
Пригласить эксперта
Ответы на вопрос 3
@lega
Нужен один составной индекс на эти 2 поля, сейчас видимо у вас 2 индекса (один на поле) и соответственно они одновременно не работают.
Ответ написан
mahoho
@mahoho
Full stack certified PHP developer.
Если у вас mysql версии 5.6+, то вам поможет секционирование по полю owner_id.
Ответ написан
Оставте один индекс на owner_id
Ответ написан
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы