Задавайте вопросы, мы ответим
Вы не зашли.
Есть таблица t с событиями d - дата и время события.
Нужно определить максимальное количество событий в минуту за сутки.
Внимание, не в конкретную минуту, а на протяжении минуты.
делаю так
Отредактированно klow (06.06.2018 22:30:24)
Неактивен
Более оптимальным алгоритмом было бы скользящее окно длительностью минуту. То есть начинаете в отсортированном по времени списке с первого id1, находите для него последний id2 в пределах минуты. Затем инкрементируете id1 и увеличиваете id2 насколько возможно для сохранения интервала в пределах минуты. Все будет сделано за один проход. Такое легко можно сделать на клиенте, но средствами MySQL это сложнее.
Неактивен
Мне кажется, задача сильно упростилась бы, если бы было «в конкретную минуту». В чем смысл скользящего окна? Мы на выходе ожидаем получить всё равно конечное количество строк (== не непрерывное), поэтому мы в любом случае будем группировать по фиксированным диапазонам времени. Ну и тогда оно решится одним полным сканом с группировкой по функции.
Ну и для наглядности пример. Пусть есть всего три события — 0:00, 0:30 и 1:00. Что мы ожидаем получить на выходе? Если [2, 1], то мой способ годится. Ваш способ, кстати, посчитает 1:00 трижды, что кажется неправильным.
Неактивен
Я тут подумал, что есть предельный случай в «непрерывной задаче» — это точность позиционирования событий. Если вы используете datetime/timestamp, то самое точное, что Вы сможете получить, — это секунды. Соответственно, можно считать количество событий в секунду, это даст наиболее точный график (ну и к RPM можно привести умножением на 60). Но опять же — я бы обошелся группировкой по минутам.
Неактивен
Спасибо за ответы!
1. Группировка по минутам может дать точность в 50%. Это многовато для моей задачи. Кстати, это было первое мое решение.
2. Использую поле DATETIME.
3. Мой алгоритм оказался не только медленным, но не точным. Если в один момент есть два (несколько) события, то результат будет задваиваться и т.д. Для меня это было неожиданно, не думал, что одновременно возможно два события. Возможно это связано с группировкой по дате.
В связи с тем, что события, в основном, идут последовательно я использовал ID (первичный ключ).
Отредактированно klow (07.06.2018 07:15:34)
Неактивен
Нужно смотреть на разницу планов исполнения (EXPLAIN).
Как задается величина @MinEvent? Решение опирается на то, что id в базе должны идти подряд без пропусков, что не гарантировано стандартом.
Неактивен
rgbeast написал:
Как задается величина @MinEvent?
Просто константа.
rgbeast написал:
Решение опирается на то, что id в базе должны идти подряд без пропусков, что не гарантировано стандартом.
Да, согласен, в общем случае это неприменимо, но в моем вполне допустимо.
Неактивен
EXPLAN при группировке по дате
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t ALL PRIMARY (null) (null) (null) 738406 Using where; Using temporary; Using filesort
1 SIMPLE c ALL PRIMARY (null) (null) (null) 738406 Range checked for each record (index map: 0x1)
Без группировки по дате
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t ALL PRIMARY (null) (null) (null) 738412 Using where; Using temporary; Using filesort
1 SIMPLE c ALL PRIMARY (null) (null) (null) 738412 Using where
Разница в количестве строк, думаю, объясняется новыми событиями между запросами.
Отредактированно klow (07.06.2018 09:39:48)
Неактивен
Все, окончательно запутался.
Сделал ограничение по дате (t.d > '2018-06-05' ) для первого случая, EXPLAN не изменился, но это предсказуемо - там нет индекса.
Сделал ограничение по ID (идут последовательно) t.id > 764900 AND c.id > 764900
EXPLAN
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t range PRIMARY PRIMARY 4 (null) 11448 Using where; Using temporary; Using filesort
1 SIMPLE c range PRIMARY PRIMARY 4 (null) 11448 Using where
Тоже все предсказуемо, но!
Время выполнения для ограничения по дате порядок(!) меньше ограничения по ID!? Это как?
кеш отключен SQL_NO_CACHE
Отредактированно klow (07.06.2018 10:25:04)
Неактивен
что будет со временем выполнения такого варианта?
Неактивен
не дождался я результата, на 10-ой минуте прервал.
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL (null) (null) (null) (null) 14952 Using temporary; Using filesort
2 DERIVED t range PRIMARY PRIMARY 4 (null) 14952 Using where; Using temporary; Using filesort
3 DEPENDENT SUBQUERY c ALL PRIMARY (null) (null) (null) 740181 Using where
Запрос, который я использую выполняется за 1,5 сек.
Остается непонятным:
1. Почему нужна группировка по дате?
2. Почему ограничение по дате (нет индекса) работает лучше чем ограничение по первичному ключу?
Отредактированно klow (07.06.2018 21:46:56)
Неактивен
Реально таблица содержит еще поля, но я их не использую для данной задачи, поэтому, думаю, они не должны влиять на результаты.
Отредактированно klow (07.06.2018 21:46:44)
Неактивен