Позвольте найти алгоритм для получения результатов с наилучшей производительностью.
- Время разделения : Время - это непрерывное измерение, нам нужно отметить несколько точек в качестве контрольной точки, куда пересчитывают слушателя. Как найти интервалы или при проверке общего радиослушателя. Я считаю, что лучшая стратегия состоит в том, чтобы получить разные
time_start
и time_end
.
Это мой подход к разделению времени. Я создаю вид для упрощения поста:
create view time_split as
select p_time from (
Select
time_start
from
your_table
union
Select
time_end
from
your_table
) as T
Предлагаю вам 2 индекса базы данных:
your_table( time_start, time_end) <--(1) explained below
your_table( time_end)
чтобы избежать сканирования таблицы.
- Подсчет пика слушателей : Соедините предыдущую таблицу со своей таблицей, чтобы пересчитать пик на каждой контрольной точке времени:
Это мой подход для подсчета количества слушателей по времени контрольной точки:
create view peak_by_time as
select p_time, count(*) as peak
from
your_table t
inner join
time_split
on time_split.p_time between t.time_start and t.time_end
group by
p_time
order by
p_time, peak
Не забудьте сделать индекс базы данных для your_table (time_start, time_end) <- (1) Здесь </p>
- Поиск максимального пика : К сожалению, MySQL не имеет аналитических функций, тогда
over partition
недоступен и не является способом получения максимального пика за день в предыдущем представлении. Тогда вы должны получить максимальный пик предыдущих просмотров. Это убийство производительности операция. Я предлагаю вам сделать эту операцию и дальше по логике приложения, а не по базе данных.
Это мой подход к получению max_peak по дням ( убийца производительности ):
create view max_peak_by_day as
select
cast(p_time as date) as p_day ,
max(peak) as max_peak
from peak_by_time
group by cast(p_time as date)
- Поиск временных интервалов : в этот момент у вас есть
max_peak
для каждого дня, теперь вам нужно искать непрерывный check times
с тем же максимальным_пиком. Также MySQL не имеет статистических функций, ни CTE. Я предлагаю вам, чтобы этот код был написан на уровне приложения. Но, если вы хотите сделать это в решении для базы данных, это способ ( предупреждение производительности убийца ):
Сначала расширьте представление peak_by_time
, чтобы получить предыдущий пик для p_time и для предыдущего p_time:
create view time_split_extended as
select c.p_time, max( p.p_time) as previous_ptime
from
time_split c
inner join
time_split p
on p.p_time < c.p_time
group by c.p_time
create view peak_by_time_and_previous as
select
te.p_time,
te.previous_ptime,
pc.peak as peak,
pp.peak as previous_peak
from
time_split_extended te
inner join
peak_by_time pc on te.p_time = pc.p_time
inner join
peak_by_time pp on te.previous_ptime = pp.p_time
Теперь убедитесь, что у предыдущего и текущего слотов есть max_peak:
select
cast(p_time as date) as p_day,
min( p_time ) as slot_from,
max( p_time) as slot_to,
peak
from
peak_by_time_and_previous p
inner join
max_peak_by_day m
on cast(p.p_time as date) = m.p_day and
p.peak = m.max_peak
where
p.peak = p.previous_peak
group by cast(p_time as date)
Ответственность
- Это не проверено. Уверены, что это ошибки с псевдонимами или столбцами таблицы.
- Последние шаги убийцы производительности . Возможно, кто-то может предложить лучший подход для этих шагов.
Кроме того, я предлагаю вам создать временные таблицы и материализовать каждое представление этого ответа. Это улучшит производительность, а также вы сможете узнать, сколько времени занимает каждый шаг.