Медленный MySQL запрос - PullRequest
       12

Медленный MySQL запрос

1 голос
/ 13 апреля 2011

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

Запрос:

SELECT DATE(DateTime) as 'SpeedDate', avg(LoadTime) as 'LoadTime'
FROM SpeedMonitor
GROUP BY Date(DateTime);

Объяснение для запроса:

id  select_type table   type    possible_keys   key key_len ref rows    Extra
1   SIMPLE  SpeedMonitor    ALL                 7259978 Using temporary; Using filesort

И структура таблицы:

CREATE TABLE `SpeedMonitor` (
  `SMID` int(10) unsigned NOT NULL auto_increment,
  `DateTime` datetime NOT NULL,
  `LoadTime` double unsigned NOT NULL,
  PRIMARY KEY  (`SMID`)
) ENGINE=InnoDB AUTO_INCREMENT=7258294 DEFAULT CHARSET=latin1;

Любая помощь будет принята с благодарностью.

Ответы [ 3 ]

3 голосов
/ 13 апреля 2011

Вы просто запрашиваете два столбца в своем запросе, поэтому индексы могут / должны идти туда:

  • DateTime
  • * 1006 время загрузки *

Другим способом ускорить ваш запрос может быть разделение поля DateTime на два: дата и время.
Таким образом, db может группировать данные непосредственно в поле даты вместо вычисления DATE (...).

РЕДАКТИРОВАНИЕ:
Если вы предпочитаете использовать триггер, создайте новый столбец (DATE) и назовите его newdate , и попробуйте с этим (я не могу попробовать сейчас, чтобы убедиться, что это правильно):

CREATE TRIGGER upd_check BEFORE INSERT ON SpeedMonitor
FOR EACH ROW
BEGIN
  SET NEW.newdate=DATE(NEW.DateTime);
END

ВНОВЬ ИЗДАНО:
Я только что создал базу данных с тем же табличным монитором скорости, заполненным около 900 000 записей.
Затем я запускаю запрос S ELECT newdate,AVG(LoadTime) loadtime FROM speedmonitor GROUP BY newdate, и это заняло около 100 секунд!
Удаление индекса для поля newdate (и очистка кеша с использованием RESET QUERY CACHE и FLUSH TABLES), тот же запрос занял 0,6 с !!!
Просто для сравнения: запрос SELECT DATE(DateTime),AVG(LoadTime) loadtime FROM speedmonitor GROUP BY DATE(DateTime) занял 0,9 с.
Поэтому я полагаю, что индекс newdate не очень хорош: удалите его.
Я собираюсь добавить как можно больше записей и снова протестировать два запроса.

ОКОНЧАТЕЛЬНОЕ РЕДАКТИРОВАНИЕ:
Удаление индексов для столбцов newdate и DateTime, имеющих 8 млн записей в таблице speedmonitor, вот результаты:

  • выбор и группировка по столбцу newdate: 7,5 с
  • выбор и группировка по полю DATE (DateTime): 13,7 с

Я думаю, это хорошее ускорение.
Время выполнения запроса в командной строке mysql.

2 голосов
/ 13 апреля 2011

Проблема в том, что вы используете функцию в предложении GROUP BY, поэтому MySQL должен оценить выражение Date(DateTime) в каждой записи, прежде чем он сможет сгруппировать результаты.Я бы предложил добавить вычисляемое поле для Date(DateTime), которое вы могли бы затем проиндексировать и посмотреть, поможет ли это вашей производительности.

0 голосов
/ 20 июля 2015

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

В настоящее время происходит то, что ваш запрос не может использовать индексы и, следовательно, сканирует всю таблицу, формируя ответ. Не самый быстрый способ работы с относительно большими таблицами.

У вас есть несколько вещей, которые нужно учитывать, если вы хотите получить лучшее состояние:

  1. Как быстро он собирает данные?
  2. Сколько истории вам нужно?
  3. Насколько детальны ваши требования к отчетности?
  4. Можете ли вы приостановить запись в журнал для внесения изменений в таблицу?

Если ответ «Нет» на последний вопрос, вы всегда можете создать новую таблицу / решение и начать записывать туда записи ... импортировать старые данные, если / как необходимо.

Детализация отчетов важна, поскольку вы можете, например, сжать данные за сутки в 24 записи. Загрузите текущий день в таблицу загрузки без индекса и затем обработайте его на следующий день в среднем за час. Назовите каждую таблицу загрузки на основе даты выборки, и вы можете удалить старые таблицы как обработанные.

Конечно, почасовая оплата может быть недостаточно мелкой.

В зависимости от ваших потребностей в хранении вы можете рассмотреть некоторые типы многораздельных хранилищ. Это может позволить вам выполнять запросы к подмножествам выборочных данных и просто отбрасывать или архивировать старые разделы, когда они недостаточно длинные, чтобы быть актуальными.

Как бы то ни было, вы, похоже, находитесь на грани того, чтобы иметь какую-то систему массового отбора проб, отчетности и / или мониторинга (особенно, если вы сообщали о различных сайтах или страницах с различными характеристиками). Возможно, вы захотите приложить некоторые усилия для разработки этого, чтобы оно соответствовало вашим потребностям ...;)

...