Поиск в MySQL очень медленный, неверный запрос или индексы?

#php #mysql #sql #performance

#php #mysql #sql #Производительность

Вопрос:

У нас есть таблица в приложении, которая ОЧЕНЬ ВЕЛИКА. Легко миллионы строк.

Структура в основном выглядит следующим образом:

 SERIES_ID | YEAR | DAY_SINCE_EPOCH | HOUR | MINUTE | VALUE
  

У нас есть индексы для YEAR и DAY_SINCE_EPOCH.

Проблема в том, что определенные запросы выполняются очень медленно, например:

 SELECT
 ...
WHERE
   SERIES_ID = 3 AND
   DAY_SINCE_EPOCH < 16000 AND
   YEAR = 2012
ORDER BY 
   DAY_SINCE_EPOCH DESC,
   HOUR DESC,
   MINUTE DESC
LIMIT 1
  

Это занимает около 10 секунд в таблице с 2 млн строк и более 20 секунд в таблице с 18 млн строк.

Цель состоит в том, чтобы найти последнюю запись серии 3 до дня 16000. Для ускорения поиска указан ГОД = 2012.

Итак, мне было интересно, правильно ли настроены индексы? Возможно, это было бы быстрее без индекса года? Или с добавленным индексом SERIES_ID или что-то в этом роде?

Или просто реструктуризация запроса поможет?

Любая идея, как ускорить поиск, будет приветствоваться!

Комментарии:

1. попробуйте составной индекс на (series_id,year,days_since_epoch)

2. У вас есть JOIN (ы) в вашем запросе?

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

4. Я также проверяю простые вещи, я предполагаю, что эти поля имеют тип INT?

5. Какой у вас сервер? И выделили ли вы достаточно памяти вашему серверу MySQL (файл my.ini)?

Ответ №1:

Этот индекс может помочь:

 > create index on your_table(series_id, day_since_epoch, year);
  

Комментарии:

1. вау, этот индекс полностью превратил улитку в гепарда! Большое спасибо, Пабло.

Ответ №2:

Проверьте эти условия

 SERIES_ID = 3 AND
DAY_SINCE_EPOCH < 16000 AND
YEAR = 2012
  

когда вы обновляете таблицу (например, сохраняете новые записи), сохраните информацию true / false в столбце «бит», а затем проверьте ее так же, как

 where checked=1 .....

 SERIES_ID | YEAR | DAY_SINCE_EPOCH | HOUR | MINUTE | VALUE | checked
  

Комментарии:

1. Как будто предложение WHERE в запросе всегда будет оставаться неизменным? 3 и 16000 и 2012?

2. Существует интерактивное представление для поиска объектов в таблице, отображения диаграммы значений за неделю и т. Д. Это не помогло бы.

3. Тогда запланированное (один раз в час) обновление может решить?