heavy database optimizions

git-svn-id: file:///home/jan/tmp/wetterstation/trunk@243 dd492736-c11a-0410-ad51-8c26713eaf7f
This commit is contained in:
jan 2008-03-20 17:09:11 +00:00
parent cbd3151a56
commit 53e83e9fd4
8 changed files with 117 additions and 83 deletions

View File

@ -20,7 +20,7 @@ class Connection{
/* Verbindung herstellen (wenn noch net besteht)*/
function _createConn(){
//print $this->conn."<br>";
#print $this->conn."<br>";
if($this->conn === NULL){
$this->conn = pg_pconnect(Config::getPgConnString())
or die('Verbindungsaufbau fehlgeschlagen: ' . pg_last_error());
@ -37,12 +37,12 @@ class Connection{
/* Eine Zeile holen */
function fetchQueryResultLine($query){
$this->_createConn();
$result = pg_query($this->conn, $query)
or die('Abfrage fehlgeschlagen: ' . pg_last_error(). "\n<br>\nquery: '".$query."'");
$array = pg_fetch_assoc($result);
//print_r($array);
return $array;
$this->_createConn();
$result = pg_query($this->conn, $query)
or die('Abfrage fehlgeschlagen: ' . pg_last_error(). "\n<br>\nquery: '".$query."'");
$array = pg_fetch_assoc($result);
//print_r($array);
return $array;
}
/* mehrere Zeilen holen */

View File

@ -40,7 +40,8 @@ class Module{
$this->modName = $modName;
$this->connection = &$connection;
$this->parserInstance = &$parser;
$this->table = $this->_getTableName();
$this->sensInstance = new Sensor($sensId, $connection);
$this->table = $this->sensInstance->get_table();
if (ModuleSet::isStandardPage($_REQUEST['setType']))
$parser->parseContent($this->_getModuleFilename("frame"), & $this, "top"); /* Oberen Modulrahmen parsen */
@ -49,13 +50,6 @@ class Module{
$parser->parseContent($this->_getModuleFilename("frame"), & $this, "bottom"); /* unteren Modulrahmen Parsen */
}
function _getTableName(){
/* Tabelle des Sensors bestimmen */
$tableQuery = "SELECT tabelle FROM sensoren, typen WHERE sensoren.id=".$this->sensId." AND typen.typ = sensoren.typ";
$table = $this->connection->fetchQueryResultLine($tableQuery);
return $table['tabelle'];
}
/* Dateinamen des Modul-Files zusammenbauen */
function _getModuleFilename($modName){
global $path;

View File

@ -43,8 +43,7 @@ class Hum{
}
function _fetchMinMax(){
$Query = "SELECT max(hum) as max, min(hum) as min FROM ".$this->table." WHERE sens_id=".$this->sensId."";
$Data = $this->connection->fetchQueryResultLine($Query);
$Data = Sensor::get_sensor_extrema($this->sensId, &$this->connection, "hum");
$this->minHum = $Data['min'];
$this->maxHum = $Data['max'];
}
@ -59,31 +58,19 @@ class Hum{
$this->maxDate = $Data[1]['text_timestamp'];
}
/* liefert den Durchschnittswert in einem bestimmtem Interval */
function _getAverage($interval){
$avQuery = "SELECT avg(hum) as average, count(hum) as count FROM ".$this->table." WHERE sens_id=".$this->sensId." AND timestamp>(current_timestamp - INTERVAL '".$interval."')";
$avData = $this->connection->fetchQueryResultLine($avQuery);
return $avData;
}
/* momentanen Durchschnittswert bestimmen */
function _fetchAverage(){
$avData = array('average'=>0, 'count'=>0); /* Array initialisieren */
$i = 1; /* Laufvariable */
while($avData['count']<5){ /* Schleife prueft, in welchem Interval 5 Werte zusammenkommen */
$i++; /* Laufvariable erhoehen */
$avData = $this->_getAverage(($i*(Config::getAvInterval()))." minutes"); /* Holt Werte mit gegebenem Interval */
}
$Data = Sensor::get_sensor_average($this->sensId, &$this->connection, "hum");
/* Werte den Klassenvariablen zuordnen */
$this->avVal = $avData['average'];
$this->avInter = $i*(Config::getAvInterval());
$this->avVal = $Data['average'];
$this->avInter = $Data['interval'];
}
/* Bestimmt die Tendenz */
function _fetchMoving(){
$shortAvData = $this->_getAverage("15 minutes"); /* Durchschnitt der letzten 15 minuten */
$longAvData = $this->_getAverage("120 minutes"); /* Durchschnitt der letzten 120 Minuten */
$shortAvData = Sensor::get_sensor_extrema($this->sensId, &$this->connection, "hum", 15); /* Durchschnitt der letzten 15 minuten */
$longAvData = Sensor::get_sensor_extrema($this->sensId, &$this->connection, "hum", 120); /* Durchschnitt der letzten 120 Minuten */
if($shortAvData['count'] < 1 || $longAvData['count'] < 2){ /* Wenn in den letzten 5 minuten kein Wert kam oder in den letzten 120 min weniger als 3 Werte kamen */
$this->changing = "Berechnung momentan nicht moeglich"; /* Dann ausgeben, dass momentan nichts berechnet werden kann */
return; /* und aus der Funktion huepfen */

View File

@ -42,8 +42,7 @@ class Press{
}
function _fetchMinMax(){
$Query = "SELECT max(press) as max, min(press) as min FROM ".$this->table." WHERE sens_id=".$this->sensId."";
$Data = $this->connection->fetchQueryResultLine($Query);
$Data = Sensor::get_sensor_extrema($this->sensId, &$this->connection, "press");
$this->minPress = $Data['min'];
$this->maxPress = $Data['max'];
}
@ -58,31 +57,19 @@ class Press{
$this->maxDate = $Data[1]['text_timestamp'];
}
/* liefert den Durchschnittswert in einem bestimmtem Interval */
function _getAverage($interval){
$avQuery = "SELECT avg(press) as average, count(press) as count FROM ".$this->table." WHERE sens_id=".$this->sensId." AND timestamp>(current_timestamp - INTERVAL '".$interval."')";
$avData = $this->connection->fetchQueryResultLine($avQuery);
return $avData;
}
/* momentanen Durchschnittswert bestimmen */
function _fetchAverage(){
$avData = array('average'=>0, 'count'=>0); /* Array initialisieren */
$i = 1; /* Laufvariable */
while($avData['count']<5){ /* Schleife prueft, in welchem Interval 5 Werte zusammenkommen */
$i++; /* Laufvariable erhoehen */
$avData = $this->_getAverage(($i*(Config::getAvInterval()))." minutes"); /* Holt Werte mit gegebenem Interval */
}
$Data = Sensor::get_sensor_average($this->sensId, &$this->connection, "press");
/* Werte den Klassenvariablen zuordnen */
$this->avVal = $avData['average'];
$this->avInter = $i*(Config::getAvInterval());
$this->avVal = $Data['average'];
$this->avInter = $Data['interval'];
}
/* Bestimmt die Tendenz */
function _fetchMoving(){
$shortAvData = $this->_getAverage("15 minutes"); /* Durchschnitt der letzten 15 minuten */
$longAvData = $this->_getAverage("120 minutes"); /* Durchschnitt der letzten 120 Minuten */
$shortAvData = Sensor::get_sensor_extrema($this->sensId, &$this->connection, "press", 15); /* Durchschnitt der letzten 15 minuten */
$longAvData = Sensor::get_sensor_extrema($this->sensId, &$this->connection, "press", 120); /* Durchschnitt der letzten 120 Minuten */
if($shortAvData['count'] < 1 || $longAvData['count'] < 2){ /* Wenn in den letzten 5 minuten kein Wert kam oder in den letzten 120 min weniger als 3 Werte kamen */
$this->changing = "Berechnung momentan nicht moeglich"; /* Dann ausgeben, dass momentan nichts berechnet werden kann */
return; /* und aus der Funktion huepfen */

View File

@ -34,13 +34,13 @@ class Rain{
/* Momentane Werte aus der Datenbank holen */
function _getNowValues($interval){
$result = $this->connection->fetchQueryResultLine("SELECT sum(count) as rain FROM ".$this->table." WHERE sens_id=".$this->sensId." AND timestamp>(current_timestamp - INTERVAL '".$interval."')");
$result = $this->connection->fetchQueryResultLine("SELECT sum(count) as rain FROM ".$this->table." WHERE sens_id=".$this->sensId." AND timestamp>(select (current_timestamp - INTERVAL '".$interval."'))");
return $result['rain'];
}
/* Maximal gemessene Werte aus der Datenbank holen */
function _getMaxValues($unit, $dateFormat){ // unit = hour, minute, ...
return $this->connection->fetchQueryResultLine("SELECT to_char(ts, '".$dateFormat."') as date, val FROM ".$this->table."_".$unit." WHERE sens_id=".$this->sensId." AND val=(SELECT max(val) FROM ".$this->table."_".$unit." WHERE sens_id=".$this->sensId.") ORDER BY ts DESC LIMIT 1");
return $this->connection->fetchQueryResultLine("SELECT to_char(ts, '".$dateFormat."') as date, val FROM ".$this->table."_".$unit." WHERE sens_id=".$this->sensId." ORDER BY val DESC, ts DESC LIMIT 1");
}

View File

@ -9,6 +9,18 @@
include_once($path."php_inc/connection.inc.php");
$sensor_data = NULL;
$extrema_fields = array(
0 => array('temp'),
1 => array('temp', 'hum'),
2 => array('count'),
6 => array('intens'),
5 => array('bight'),
4 => array('temp', 'hum', 'press'),
3 => array('geschw')
);
$sensor_extrema = array();
$sensor_average = array();
/* Klasse, Die Daten ueben die Einzelnen Sensoren bereitstellt */
class Sensor{
@ -18,22 +30,30 @@ class Sensor{
var $descr; /* Beschreibung des Sensors */
var $typ; /* Typ des Sensors */
var $address; /* Addresse des Sensors */
var $tabelle; /* Tabelle in der die Werte des Sensors stehen */
/* Konstruktor, Initialisiert die Klasse mit den Werten */
function Sensor($sensId, & $connection){
$this->_fetchSensorData($sensId, &$connection);
}
/* Holt die Daten ueber den Sensor aus der Datenbank */
function _fetchSensorData($sensId, &$connection){
$query = "SELECT * FROM sensoren WHERE id=".$sensId;
$data = $connection->fetchQueryResultLine($query);
$data = $this->_fetchSensorData($sensId, &$connection);
$this->id = $data['id'];
$this->location = $data['standort'];
$this->descr = $data['beschreibung'];
$this->typ = $data['typ'];
$this->address = $data['addresse'];
$this->table = $data['tabelle'];
}
/* Holt die Daten ueber den Sensor aus der Datenbank */
function _fetchSensorData($sensId, &$connection){
global $sensor_data;
if ($sensor_data == NULL){
$query = "SELECT sensoren.*, typen.tabelle FROM sensoren, typen where typen.typ = sensoren.typ";
$result = $connection->getRawResult($query);
while ($array = pg_fetch_assoc($result)){
$sensor_data[$array['id']] = $array;
}
}
return $sensor_data[$sensId];
}
/* --- Funktionen, die die Einzelnen Eigenschaften des Sensors zurueckgeben --- */
@ -56,6 +76,65 @@ class Sensor{
function get_address(){
return $this->address;
}
function get_table(){
return $this->table;
}
/* Statisch,
* Holt Extrema (Min/Max)
* Braucht: Sensor-Id, Connection, Das Feld fuer das die Extrema ausgegeben werden sollen */
function get_sensor_extrema($sensId, &$connection, $field){
global $extrema_fields, $sensor_extrema;
if (! array_key_exists($sensId, $sensor_extrema)){
$data = Sensor::_fetchSensorData($sensId, &$connection);
$query = "SELECT ";
for ($i = 0; $i < count($extrema_fields[$data['typ']]); $i++){
if ($i != 0)
$query .= ", ";
$query .= "min(".$extrema_fields[$data['typ']][$i].") AS min_".$extrema_fields[$data['typ']][$i].", ";
$query .= "max(".$extrema_fields[$data['typ']][$i].") AS max_".$extrema_fields[$data['typ']][$i]." ";
}
$query .= "FROM ".$data['tabelle']." WHERE sens_id = ".$sensId;
$res = $connection->fetchQueryResultLine($query);
$sensor_extrema[$sensId] = $res;
}
return array('min' => $sensor_extrema[$sensId]['min_'.$field], 'max' => $sensor_extrema[$sensId]['max_'.$field]);
}
/* Statisch,
* Holt Durchschnittswerte
* Braucht: Sensor-Id, Connection, Das Feld fuer das die Extrema ausgegeben werden sollen,
* optional ein interval ueber das gemittelt werden soll */
function get_sensor_average($sensId, &$connection, $field, $init_interval = 0){
global $extrema_fields, $sensor_average;
if ((! array_key_exists($init_interval, $sensor_average)) || (! array_key_exists($sensId, $sensor_average[$init_interval]))){
$interval = $init_interval;
$data = Sensor::_fetchSensorData($sensId, &$connection);
$query = "SELECT count(".$extrema_fields[$data['typ']][0].") AS count, ";
for ($i = 0; $i < count($extrema_fields[$data['typ']]); $i++){
if ($i != 0)
$query .= ", ";
$query .= "avg(".$extrema_fields[$data['typ']][$i].") AS ".$extrema_fields[$data['typ']][$i]." ";
}
$query .= "FROM ".$data['tabelle']." WHERE sens_id = ".$sensId." AND timestamp>(select(current_timestamp - INTERVAL '";
$res = array('count' => 0, 'average' => 0);
$m = 0;
if ($interval == 0){
while ($res['count'] < 4) {
$m++;
$interval = $m*(Config::getAvInterval());
$res = $connection->fetchQueryResultLine($query.$interval." minutes'))");
}
} else {
$res = $connection->fetchQueryResultLine($query.$interval." minutes'))");
}
$res['interval'] = $interval;
$sensor_average[$init_interval][$sensId] = $res;
}
return array('average' => $sensor_average[$init_interval][$sensId][$field], 'count' => $sensor_average[$init_interval][$sensId]['count'], 'interval' => $sensor_average[$init_interval][$sensId]['interval']);
}
}
?>

View File

@ -42,8 +42,7 @@ class Temp{
}
function _fetchMinMax(){
$Query = "SELECT max(temp) as max, min(temp) as min FROM ".$this->table." WHERE sens_id=".$this->sensId."";
$Data = $this->connection->fetchQueryResultLine($Query);
$Data = Sensor::get_sensor_extrema($this->sensId, &$this->connection, "temp");
$this->minTemp = $Data['min'];
$this->maxTemp = $Data['max'];
}
@ -58,31 +57,19 @@ class Temp{
$this->maxDate = $Data[1]['text_timestamp'];
}
/* liefert den Durchschnittswert in einem bestimmtem Interval */
function _getAverage($interval){
$avQuery = "SELECT avg(temp) as average, count(temp) as count FROM ".$this->table." WHERE sens_id=".$this->sensId." AND timestamp>(current_timestamp - INTERVAL '".$interval."')";
$avData = $this->connection->fetchQueryResultLine($avQuery);
return $avData;
}
/* momentanen Durchschnittswert bestimmen */
function _fetchAverage(){
$avData = array('average'=>0, 'count'=>0); /* Array initialisieren */
$i = 1; /* Laufvariable */
while($avData['count']<5){ /* Schleife prueft, in welchem Interval 5 Werte zusammenkommen */
$i++; /* Laufvariable erhoehen */
$avData = $this->_getAverage(($i*(Config::getAvInterval()))." minutes"); /* Holt Werte mit gegebenem Interval */
}
$Data = Sensor::get_sensor_average($this->sensId, &$this->connection, "temp");
/* Werte den Klassenvariablen zuordnen */
$this->avVal = $avData['average'];
$this->avInter = $i*(Config::getAvInterval());
$this->avVal = $Data['average'];
$this->avInter = $Data['interval'];
}
/* Bestimmt die Tendenz */
function _fetchMoving(){
$shortAvData = $this->_getAverage("15 minutes"); /* Durchschnitt der letzten 15 minuten */
$longAvData = $this->_getAverage("120 minutes"); /* Durchschnitt der letzten 120 Minuten */
$shortAvData = Sensor::get_sensor_extrema($this->sensId, &$this->connection, "temp", 15); /* Durchschnitt der letzten 15 minuten */
$longAvData = Sensor::get_sensor_extrema($this->sensId, &$this->connection, "temp", 120); /* Durchschnitt der letzten 120 Minuten */
if($shortAvData['count'] < 1 || $longAvData['count'] < 2){ /* Wenn in den letzten 5 minuten kein Wert kam oder in den letzten 120 min weniger als 3 Werte kamen */
$this->changing = "Berechnung momentan nicht moeglich"; /* Dann ausgeben, dass momentan nichts berechnet werden kann */
return; /* und aus der Funktion huepfen */

View File

@ -126,7 +126,7 @@ class Wind{
/* liefert den Durchschnittswert in einem bestimmtem Interval */
function _getAverage($interval){
$avQuery = "SELECT avg(geschw) as average, count(geschw) as count FROM ".$this->table." WHERE sens_id=".$this->sensId." AND timestamp>(current_timestamp - INTERVAL '".$interval."')";
$avQuery = "SELECT avg(geschw) as average, count(geschw) as count FROM ".$this->table." WHERE sens_id=".$this->sensId." AND timestamp>(select (current_timestamp - INTERVAL '".$interval."'))";
$avData = $this->connection->fetchQueryResultLine($avQuery);
return $avData;
}