2012-07-23 87 views
2

此脚本使用PHP和MySQL来计算在一分钟移动平均,以减少异常值对我的数据的影响(1分= 6 10第二行)。它可以正确计算所有内容,但一次不足150行。我希望一次能做到尽可能多的行数,可能在5-10,000之间,因为我的表格超过150,000,并且每天输入大约8000行。滚动平均效率,PHP的MySQL

有没有人有任何建议,我怎样才能使这个脚本更有效地运行?

谢谢!

<?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'"); 
} 
+0

你需要使用MySQL吗?它看起来不像你需要它。 – Esailija 2012-07-23 13:55:47

+0

如[mysql_query()'](http://php.net/manual/en/function.mysql-query.php)函数的PHP手册所述:*不推荐使用此扩展名。相反,[MySQLi](http://www.php.net/manual/en/book.mysqli.php)或[PDO_MySQL](http://www.php.net/manual/en/ref.pdo-应该使用mysql.php)扩展名。另请参见[MySQL:选择API](http://www.php.net/manual/en/mysqlinfo.api.choosing.php)指南和[相关FAQ](http://www.php.net/manual /en/faq.databases.php#faq.databases.mysql.depcated)以获取更多信息。* – eggyal 2012-07-23 14:02:13

+0

我开始使用MySQL自动执行分析,而不是使用Excel,有没有其他方法可以提示? – user1537931 2012-07-23 14:09:35

回答

1

对于初学者来说,最初的“伯爵”在这里块可以通过添加COUNT()总被清理。没有它,你会从表格中选择所有的数据 - 一个查询只会放入表格中的数据越慢。

为你计算的平均值,有不能在MySQL查询直接完成所需的任何逻辑是什么?例如:

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

这可以帮助您避免在结果中循环,如果可能的话。

+0

谢谢!这可能工作,有没有什么办法选择正确的6行使用该查询?我唯一担心的是如果timestamp列中存在非连续行。 – user1537931 2012-07-23 14:20:21

+0

是的,你应该能够像'=(SELECT AVG(PortRPMSignal)FROM表WHERE时间戳BETWEEN'$ startTime'AND'$ endTime'LIMIT 6)'那样限制子查询。鉴于它是基于时间的,是否有可能存在不连续的行? – newfurniturey 2012-07-23 14:23:07

+0

是的,一些行必须被删除,所以时间不总是连续的。该限制可能会工作,虽然 – user1537931 2012-07-23 14:28:43

0

这只是一个开始,但你可以斌此位

//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结果集上。

使用在查询中*增加了数据库的负载。

在你的循环,你再有这

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

这意味着该查询运行每次循环,你甚至不使用效果。

我不知道mysqli是否会给你更好的表现,但你应该使用它。

$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>"; 

这应该对自己大大加快速度

+1

我对mysqli并不熟悉,但我会研究一下,谢谢! – user1537931 2012-07-23 14:12:24

1

这听起来像你试图计算自回归移动平均(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 

虽然一个更好的解决方案,如果你没有一个完整的数据集,但有只抖动少量是使用一个自动增加ID的模量从“一”

挑出更少的行
+0

我一直在寻找这个。当你没有合适的词汇来描述你所需要的东西时,很难找到它。 自回归移动平均值。 你是我的英雄。 – abase 2013-07-25 01:55:35