Назад | Перейти на главную страницу

Почему MySQL использует разные индексы для моего запроса в разных версиях?

У меня есть большая таблица InnoDB (около 800 МБ), и я хотел бы подсчитать строки. Я знаю SELECT COUNT(*) есть проблемы в InnoDB, но одно из решений, которые я видел, - создать вторичный индекс, что намного быстрее, чем пережевывание PRIMARY, по крайней мере, для количества строк.

Я скопировал содержимое таблицы на второй сервер. Сервер работает быстрее, и, конечно же, в результате копирования получилась красивая компактная таблица, которая не претерпела удалений и обновлений. Итак, на новом сервере все идет хорошо и быстро, но кое-что в поведении старого сервера все еще меня озадачивает:

у меня есть PRIMARY index и еще один индекс (назовите его index2) уже определено в таблице. На старом сервере (MySQL 5.0.27) я могу EXPLAIN SELECT COUNT(*) FROM myTable и увидите, что он будет использовать PRIMARY индекс. Запрос занимает больше минуты. Если я SELECT COUNT(*) FROM myTable USE INDEX(index2), это занимает ~ 100 мс. Если я положу WHERE someCol > lowest_possible_value он также выбирает более быстрый индекс.

На новом сервере (MySQL 5.1.52) то же EXPLAIN заявление говорит мне, что он будет использовать index2, без намека. Простой SELECT COUNT(*) FROM myTable очень быстро, порядка 20-30 мс. Я могу бегать SELECT COUNT(*) FROM myTable USE INDEX(PRIMARY), чтобы заставить его использовать «плохой» индекс, а это занимает больше времени - всего 3-4 секунды, но, как я уже сказал, есть и другие отличия, которые можно учесть, и это все равно более чем в сто раз медленнее, чем «хороший» (неPRIMARY) индекс.

Почему новый экземпляр MySQL выбирает «правильный» индекс? Могу ли я сделать что-нибудь на старом сервере, чтобы воспроизвести такое поведение? Я бы хотел избежать полного обновления прямо сейчас, но это не исключено.

Две возможности:

  1. Тот факт, что это новая таблица, означает, что статистика, которую MySQL использует, чтобы попытаться оценить, какой индекс является правильным для использования, отличается.
  2. Более новая версия MySQL умнее.

Исправить первое может быть так же просто, как ANALYZE TABLE; исправление последнего - это просто обновление пакета.