MySQL Запрос медленный с ORDER BY - PullRequest
0 голосов
/ 30 января 2020

Итак, у меня проблема, когда я добавляю ORDER BY date_last_access DESC, весь запрос замедляется до 3 сек, а без него - около 0.2 сек, почему он работает так медленно и как я могу изменить запрос, чтобы он выполнялся быстрее?

Есть также индексы для всех используемых таблиц и полей.

Пользователи: 1+ миллионов записей Нравится: 5+ миллионов записей (более 1 миллиарда в производстве)

Таблицы будут растет очень быстро, как только начнется производство * ИНДЕКСЫ

НРАВИТСЯ - user_id, judged_user - НОРМАЛЬНО - BTREE

ПОЛЬЗОВАТЕЛИ - id, gender, date_birth, status, date_last_access - НОРМАЛЬНЫЙ - BTREE

Когда я заказываю по id вместо date_last_access, кажется, что он работает намного быстрее, может ли это быть причиной того, что date_last_access имеет формат datetime?

Ответы [ 3 ]

1 голос
/ 30 января 2020

Простое указание подзапроса может быть лучшим способом избежать дополнительного времени обработки (COUNT):

(SELECT COUNT(*) FROM likes WHERE likes.judged_user = users.id AND likes.user_id = {UID}) = 0

может измениться на

(SELECT 1 FROM likes WHERE likes.judged_user = users.id AND likes.user_id = {UID} limit 1) IS NULL

Избегание подзапроса может быть лучшим способом улучшить производительность запроса. Вы можете проверить, какие варианты могут быть лучше для вашего случая (в этом случае требуется индекс для likes.user_id)

FROM
    users
LEFT JOIN (
SELECT distinct judged_user FROM likes WHERE likes.user_id = {UID}
) l ON l.judged_user=users.id
WHERE
    `id` != {UID} AND
    `gender` = {GEND} AND
    `date_birth` BETWEEN {DOB_MIN} AND {DOB_MAX} AND
    `status` = 'active' AND
    l.judged_user is NULL
1 голос
/ 30 января 2020

Сначала попробуйте выполнить EXPLAIN вашего запроса. Это покажет вам, какие поля и операции замедляют ваш запрос. Затем попробуйте создать объединения с индексированными столбцами и отфильтруйте набор результатов с более конкретными значениями c.

0 голосов
/ 30 января 2020

Вы должны сформулировать предложение FROM как:

WHERE `id` <> {UID} AND
      `gender` = {GEND} AND
      `date_birth` BETWEEN {DOB_MIN} AND {DOB_MAX} AND
      `status` = 'active' AND
       NOT EXISTS (SELECT 1 FROM likes l WHERE l.judged_user = users.id AND l.user_id = {UID}) 
HAVING distance <= {DIST}

Для этого запроса вы можете попробовать два индекса:

  • LIKES(judged_user, user_id)
    • USERS(Gender, status, date_birth, id)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...