Средняя скорость прокатки, php mysql

Этот скрипт использует php и mysql для вычисления скользящего среднего за минуту, чтобы уменьшить влияние выбросов на мои данные (одна минута = 6 10-секундных рядов). Он правильно вычисляет все, но недостаточно эффективен, чтобы делать более 150 строк за раз. Я хотел бы делать столько строк, сколько могу за один раз, возможно, между 5-10 000, поскольку моя таблица превышает 150 000, и я вводил приблизительно 8000 строк в день.

Есть ли у кого-нибудь какие-либо предложения относительно того, как я могу сделать этот скрипт более эффективным?

Благодаря!

<?php //connect to database mysql_connect("localhost","user","password");//database connection mysql_select_db("database"); $result = mysql_query("SELECT Timestamp FROM table"); if (!$result) { die('Could not query:' . mysql_error()); } //get number of rows in table $resultA = mysql_query("SELECT * FROM table"); $num_rows = mysql_num_rows($result); echo "There are $num_rows rows.</br>"; //select column to be averaged $resultB = mysql_query("SELECT PortRPMSignal FROM table"); if (!$resultB) { die('Could not query:' . mysql_error()); } //set start equal to the first row you want to calculate the averages from, likely the first null row $start = 5; //calculate 1 minute average, the average is correct for($i = $start; $i<$num_rows; $i++){ $output = mysql_result($result,$i); $test = mysql_result($resultB,$i)+mysql_result($resultB,$i-1)+mysql_result($resultB,$i-2)+mysql_result($resultB,$i-3)+mysql_result($resultB,$i-4)+mysql_result($resultB,$i-5); $test2 = $test/6; $round = round($test2,4); $temp = mysql_query("SELECT Timestamp FROM table"); if(!$temp){ die('Could not query:' . mysql_error()); } //gets timestamp at row $i, and inserts new average value into that row in RPMAve column $time = mysql_result($result,$i); mysql_query("UPDATE table SET PortMinuteAveRPM = $round WHERE Timestamp = '$time'"); } 

    Во-первых, начальный блок «count» здесь можно очистить, добавив агрегат COUNT() :

     $resultA = mysql_query("SELECT * FROM table"); $num_rows = mysql_num_rows($result); echo "There are $num_rows rows.</br>"; 

    Изменить на:

     $resultA = mysql_query("SELECT COUNT(*) FROM table"); $row = mysql_fetch_array($result); $num_rows = $row[0]; echo "There are $num_rows rows.</br>"; 

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

    Для средних значений, которые вы вычисляете, существует ли какая-либо логика, которая не может быть выполнена непосредственно в запросе MySQL? Что-то вроде:

     UPDATE table SET PortMinuteAveRPM=(SELECT AVG(PortRPMSignal) FROM table WHERE Timestamp BETWEEN '$startTime' AND '$endTime') WHERE TimeStamp='$endTime' 

    Это может спасти вас от перебора результатов, если это правдоподобно.

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

    Если у вас есть полный набор данных (хотя ваш вопрос подразумевает, что вы этого не делаете), то определите, какой временной интервал содержит требуемое количество записей и получить его непосредственно из базы данных, например

     SELECT a.timestamp as base, AVG(b.PortRPMSignal) FROM table a, table b WHERE b.timestamp BETWEEN a.timestamp AND a.timestamp+INTERVAL 6 HOUR GROUP BY a.timestamp 

    Если вы хотите выровнять данные, то попробуйте что-то вроде ….

     SELECT a.timestamp as base, AVG(b.PortRPMSignal) FROM table a, table b WHERE b.timestamp BETWEEN a.timestamp AND a.timestamp+INTERVAL 6 HOUR AND DATE_FORMAT(a.timestamp, '%i%s')='0000' GROUP BY a.timestamp 

    Хотя лучшее решение, если у вас нет полного набора данных, но только небольшое количество дрожания будет заключаться в использовании модуля идентификатора автоматического инкремента, чтобы выделять меньше строк из 'a'

    Это только начало, но вы можете бить этот бит

     //get number of rows in table $resultA = mysql_query("SELECT * FROM table"); $num_rows = mysql_num_rows($result); echo "There are $num_rows rows.</br>"; 

    Потому что следующая строка

     $resultB = mysql_query("SELECT PortRPMSignal FROM table"); 

    … даст вам набор результатов, в котором вы можете использовать mysql_num_rows.

    Использование * в запросе увеличивает нагрузку на базу данных.

    В вашем цикле for вы

     $temp = mysql_query("SELECT Timestamp FROM table"); if(!$temp){ die('Could not query:' . mysql_error()); } 

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

    Я не знаю, даст ли mysqli лучшую производительность, но вы должны его использовать.