MySQL, удалить и индексировать подсказку - PullRequest
11 голосов
/ 28 мая 2010

Мне нужно удалить около 10 тысяч строк из таблицы, которая содержит более 100 миллионов строк на основе некоторых критериев. Когда я выполняю запрос, это занимает около 5 минут. Я выполнил план объяснения (запрос delete преобразован в select *, поскольку MySQL не поддерживает explain delete) и обнаружил, что MySQL использует неправильный индекс.

Мой вопрос: есть ли способ сообщить MySQL, какой индекс использовать во время удаления? Если нет, то что я могу сделать? Выбрать временную таблицу, а затем удалить из временной таблицы?

Ответы [ 3 ]

4 голосов
/ 28 мая 2010

Синтаксис подсказки индекса . //ETA: sadly, not for deletes

ETA: Вы пробовали запустить ANALYZE TABLE $mytable?

Если это не окупится, я думаю, что у вас есть 2 варианта: удалить поврежденный индекс перед удалением и заново создать его после. Или СОЕДИНИТЕ свою таблицу удаления к другой таблице по нужному индексу, которая должна гарантировать, что нужный индекс используется.

2 голосов
/ 28 мая 2010

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

Возможно, вы захотите проверить эту книгу: http://oreilly.com/catalog/9780596003067

В нем есть отличный раздел о том, как работают индексы и другие параметры настройки.

0 голосов
/ 05 августа 2018

Как указано в других ответах, MySQL не может использовать индексы, кроме индекса PRIMARY KEY.

Таким образом, ваш лучший вариант, если у вас есть ПЕРВИЧНЫЙ КЛЮЧ на столе, это выполнить быстрый SELECT, а затем УДАЛИТЬ в соответствии со строками. Желательно в транзакции, чтобы вы не удаляли неправильные строки.

Таким образом:

DELETE FROM table WHERE column_with_index = 0

Будет переписано:

SELECT primary_key FROM table WHERE column_with_index = 0 => возвращает много строк

DELETE FROM table WHERE primary_key IN(?, ?, ?) => ? будет заменен результатами ВЫБРАННЫХ первичных ключей.

Если у вас не так много строк для удаления, это будет более эффективным способом.

Например, я только что натолкнулся на пример на той же таблице с теми же данными:

  • 7499067 строк проанализировано с помощью DELETE: 12 секунд

против

  • 6 строк, проанализированных с помощью SELECT с использованием хорошего индекса: 0,10 секунд
  • 0 строк, которые будут удалены в конце
...