У меня есть база данных, содержащая записи, собираемые каждые 0,1 секунды, и мне нужно усреднять данные по времени с заданного дня до одного раза каждые 20 минут. Поэтому мне нужно вернуть данные за день, усредненные каждые 20 минут, что составляет 24*3 значений.
В настоящее время я делаю отдельный вызов AVG к базе данных для каждого 20-минутного периода в течение дня, что составляет 24*3. звонки. Мое подключение к базе данных кажется немного медленным (оно удаленное), и все средние значения занимают около 5 минут. Было бы быстрее выполнить один запрос, в котором я получаю доступ к данным за весь день, а затем усредняю их каждые 20 минут? Если это поможет ответить на вопрос, я должен выполнить некоторые арифметические действия с данными перед усреднением, а именно умножить несколько столбцов таблицы.
Ускорение доступа к базе данных
Ответы (7)
Вы можете рассчитать количество минут с полуночи, например:
datepart(hh,datecolumn)*60 + datepart(mi,datecolumn)
Если вы разделите это на 20, вы получите номер 20-минутного интервала. Например, 00:10
попадает в интервал 0
, 00:30
— в интервал 1
, 15:30
— в интервал 46
и так далее. С помощью этой формулы вы можете группировать по 20-минутным интервалам, например:
select
(datepart(hh,datecolumn)*60 + datepart(mi,datecolumn)) / 20 as IntervalNr
, avg(value)
from YourTable
group by (datepart(hh,datecolumn)*60 + datepart(mi,datecolumn)) / 20
Вы можете выполнять математические операции внутри вызова avg
, например:
avg(col1 * col2 - col3 / col4)
В целом сокращение количества запросов — хорошая идея. Агрегируйте и выполняйте любую арифметику/фильтрацию/группировку, которую вы можете в запросе (т.е. в базе данных), а затем выполняйте «итеративные» вычисления на стороне сервера (например, в PHP).
Чтобы быть уверенным, будет ли это быстрее или нет, его следует измерить.
Однако это должно быть быстрее, так как у вас медленное соединение с базой данных, и таким образом количество обращений в оба конца больше влияет на общее время выполнения.
Как насчет хранимой процедуры в вашей базе данных? Если ваш механизм базы данных не поддерживает его, как насчет того, чтобы иметь сценарий или что-то еще, выполняющее математические операции и заполняющие отдельную таблицу «средних значений» на вашем сервере базы данных. Тогда вам нужно только считывать средние значения с удаленного клиента только один раз в день.
Вычисление в одном запросе будет немного быстрее. Подумайте о накладных расходах на несколько запросов, таких как установка соединения, анализ запроса или загрузка хранимой процедуры и т. д.
Но также убедитесь, что у вас есть точные показатели, которые могут привести к огромному увеличению производительности. Некоторые операции с огромными базами данных могут длиться от минут до часов.
Если вы отправляете много данных, а соединение является узким местом, то как и когда вы группируете и отправляете данные, не имеет значения. Нет хорошего способа отправлять 100 МБ каждые 10 минут через модем 56k. Выясните размер ваших данных и пропускную способность и убедитесь, что вы даже можете отправить их.
Это сказало:
Сначала убедитесь, что сеть является узким местом. Если это так, попробуйте по возможности работать с меньшим набором данных и протестируйте разные сценарии. Как правило, 1 большой набор записей использует меньшую полосу пропускания, чем 2 набора записей вдвое меньшего размера.
Если возможно, добавьте столбцы в свою таблицу и вычисляйте и сохраняйте произведение столбца и индекс интервала (см. сообщение Andomar) каждый раз, когда вы отправляете данные в базу данных.