MySQL 8 медленный с нисходящим составным индексом - PullRequest
0 голосов
/ 21 апреля 2019

У меня следующий запрос:

SELECT 
      shows.id, 
      shows.title, 
      shows.thumbnail, 
      shows.views, 
      shows.likes, 
      shows.dislikes, 
      shows.duration, 
      shows.hd, 
      shows.origin, 
      UNIX_TIMESTAMP(shows.upload_date) as upload_date 
   FROM 
      shows 
   WHERE 
          (shows.views, shows.id) < (0, 272990) 
      and shows.visible = 1 
   ORDER BY 
      shows.views DESC, 
      shows.id DESC 
   LIMIT 
      32

Это занимает около 0,8 секунд в MySQL 8.0.15.

Я пробовал индексы, подобные этому:

CREATE INDEX views_desc_id_desc_visible ON shows (views desc, id desc, visible)

Так же, как и такие:

CREATE INDEX views_desc_id_desc ON shows (views desc, id desc)

и многие другие перестановки.Я удалял их и много раз переделывал с нуля.Visible имеет индекс на себя.

Когда я делаю expain, я вижу, что он выполняет только «Используя где», используя ключ с именем views_desc_id_desc_visible.Удаление видимого из запроса не меняет его производительность.Удаление двух дескрипторов (так: упорядочение по представлениям, идентификатору) делает его 0,0008 секунд.

Почему это не происходит быстрее?

Обновление (скопировано из комментария)

SELECT  shows.id, shows.title, shows.thumbnail, shows.views, shows.likes,
        shows.dislikes, shows.duration, shows.hd, shows.origin,
        UNIX_TIMESTAMP(shows.upload_date) as upload_date
    FROM  shows
    WHERE      (shows.views <= 0)
      and  not (shows.views  = 0 and shows.id >= 272990)
      and  visible = 1
    ORDER BY  shows.views DESC, shows.id DESC
    LIMIT  32

исправляет это.Я просто не знаю, почему использование этого способа игнорирует индексы.

1 Ответ

2 голосов
/ 28 апреля 2019

visible должен прийти первым в индексе.

INDEX(visible, views DESC, id DESC)

Общее правило построения оптимального индекса:

  1. Включить все столбцыв WHERE, которые тестируются с = constant.
  2. Затем другие столбцы.

Подробнее: http://mysql.rjweb.org/doc.php/index_cookbook_mysql

Существует возможная проблема с «конструктором строк», который вы используете с WHERE (shows.views, shows.id) < (0, 272990).По существу, это не оптимизировалось вообще до 5.7.

Обходной путь (до 5.7) заключался в том, что сложное выражение, упомянутое вами в вашем комментарии, было оптимизировано.Вероятно, он все еще оптимизирован:

WHERE      (shows.views <= 0)
  and  not (shows.views  = 0 and shows.id >= 272990)

8.0 введен с соблюдением DESC в объявлениях индекса.

Я обеспокоен тем, что оптимизатору не удалось соединить эти два усовершенствования, чтобы сделать то, что вы делаетеищу.

Пожалуйста, покажите нам EXPLAIN SELECT... за ваши попытки.Особенно обратите внимание на Key_len.

Даже без 8.0 я бы порекомендовал

INDEX(visible, views, id)

. В этом случае индекс можно перемещать назад для обработки

WHERE visible = 0
  AND ...
ORDER BY views DESC, id DESC

Это при условии, что проблемы с конструктором строк решены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...