Почему порядок по первичному индексу делает этот запрос медленным? - PullRequest
1 голос
/ 11 декабря 2011

Этот запрос получает новейшие видео, загруженные по подписке пользователя, он работает очень медленно, поэтому я переписал его для использования объединений, но это не имело значения, и, поработав с ним, я обнаружил, что удаление ORDER BY сделает егоработать быстро (однако это не соответствует цели запроса).

Запрос:

SELECT vid. *
FROM video AS vid
INNER JOIN subscriptions AS sub ON vid.uploader = sub.subscription_id
WHERE sub.subscriber_id = '1'
AND vid.privacy = 0 AND vid.blocked <> 1 AND vid.converted = 1
ORDER BY vid.id DESC
LIMIT 8

При выполнении объяснения будет показано «Использование временного; Использование сортировки файлов» в таблице подписок и его медленный (0,0900 секунд).

Без ORDER BY vid.id DESC он не показывает «Использование временного; Использование сортировки файлов», поэтому он быстрый (0,0004 секунды), но я не понимаю, как другая таблица может повлиять на это, как это.

Все поля проиндексированы (конфиденциальность заблокирована, а преобразованные поля не влияют на производительность более чем на 10%).

Я вставил бы полную информацию объяснения, но я не могу привести ее в соответствиеприятно в макете этого сайта.

Ответы [ 2 ]

3 голосов
/ 11 декабря 2011

Вы ограничиваете запрос до 8 результатов. Когда вы запускаете его без order by, он может захватить первые 8 встреченных строк, которые проходят условие, а затем вернуть их обратно. Бум, готово.

Когда вы используете order by, вы не запрашиваете никаких 8 записей. Вы запрашиваете первые 8 записей в терминах vid.id. Таким образом, он должен выяснить, что это такое, и единственный способ сделать это - просмотреть всю таблицу и сравнить значения vid.id. Это намного больше работы.

Есть ли на самом деле индекс по столбцу? Если так, это может быть устаревшим. Вы можете попробовать восстановить его.

1 голос
/ 11 декабря 2011

Исправлено, предлагая MySQL использовать первичный индекс с USE_INDEX (PRIMARY)

SELECT vid. *
FROM video AS vid USE INDEX ( PRIMARY )
INNER JOIN subscriptions AS sub ON vid.uploader = sub.subscription_id
WHERE sub.subscriber_id = '1'
AND vid.privacy =0
AND vid.blocked <>1
AND vid.converted =1
ORDER BY vid.id DESC
LIMIT 8
...