Sparsame (komplexe) Zugriffstatistik + Reloadsperre?

charlie71

Grünschnabel
Guten Tag allerseits,

ich arbeite momentan an einem Adserver Script für ein Werbenetzwerk und habe noch Probleme mit dem hohen Perfomance Verbrauch. Nun frage ich mich ob es eine Möglichkeit gibt eine Reloadsperre und eine Statistik ohne MySQL zu verwirklichen, vll mit XML? Das Problem ist, das es relativ komplex ist da für jedes Werbemittel das ein Webmaster anlegt, eine neue Statistik geführt werden muss und die Reloadsperre ohne Cookies arbeiten soll.

Habt ihr da vll einige Tipps zu diesen Thema? Grade für den Bereich gibt es wenige Referenzen, es gibt zwar etliche Open-Source AdServer aber diese an meinen Zweck anzupassen wäre wahrscheinlich mehr Arbeit als es von Grund auf neu zu schreiben. Mit MySQL ist es natürlich sehr einfach und komfortabel, aber wie bereits erwähnt natürlich sehr Perfomancelastig... die Reloadsperre lässt sich zwar mit Cookies realisieren, aber die ist dann nicht sehr genau da viele ja keine Cookies zulassen.

Ich bin für absolut jeden Vorschlag offen, ob nun mit MySQL oder ohne - es geht nur um die Performance.
Hier mal meine aktuelle Statistik + Reloadsperre die bei jedem Werbemittelaufruf ausgeführt wird:

PHP:
<?
// ad_id ist die Werbemittel ID, die wird via $_REQUEST geholt.
// user_id klar: Die Webmaster ID, die auch via $_REQUEST gehotl wird.
// 
// Statistik lesen
$today = date("z");
   $sql = "select ad_id, day_id from ad_stat where ad_id = '$ad_id' AND day_id ='$today'";
   $res = mysql_query($sql);
   
// Neu anlegen wenn für das Werbemittel noch keine Daten verfügbar sind
   if (mysql_num_rows($res) == 0)
   {	  
	  $sql = "INSERT INTO ad_stat (ad_id, user_id, ad_kind, ad_ref, day_id, day_value, week_id, week_value, month_id, month_value, year_id, year_value, all_value, record_date, record_value) VALUES ('$ad_id', '$user_id', '$ad_kind', '$ad_ref', '" . date("z") . "',  '1', '" . date("W") . "', '1', '" . date("n") . "', '1', '" . date("Y") . "',  '1',  '1',  NOW(),  '1')";
	  mysql_query($sql);

	  $sql = "select ad_id, day_id from ad_stat WHERE ad_id = '$ad_id' AND day_id = '$today'";
      $res = mysql_query($sql);
	  
	  $ignore = true;
   } 
   $row = mysql_fetch_assoc($res);
   $cid = $row['day_id'];
   $day_id = $row['day_id'];
   $day_value = $row['day_value'];
   $week_id = $row['week_id'];
   $week_value = $row['week_value'];
   $month_id = $row['month_id'];
   $month_value = $row['month_value'];
   $year_id = $row['year_id'];
   $year_value = $row['year_value'];
   $all_value = $row['all_value'];
   $record_date = $row['record_date'];
   $record_value = $row['record_value'];
   $counter_expire = $ad_reload*60;
   $counter_agent = (isset($_SERVER['HTTP_USER_AGENT'])) ? addslashes(trim($_SERVER['HTTP_USER_AGENT'])) : "";
   $counter_time = time();
   $counter_ip = trim(addslashes($_SERVER['REMOTE_ADDR'])); 
// Bots ignorieren
   if (substr_count($counter_agent, "bot") > 0)
      $ignore = true;
      
// Reloadsperre: Abgelaufene Daten leeren
   if (@$ignore == false)
   {
      $sql = "delete from ad_count where unix_timestamp(NOW())-unix_timestamp(visit) > $counter_expire AND ad_id='$ad_id'"; 
      mysql_query($sql);
   }
      
// Reloadsperre: Prüfen ob IP schon vorhanden
   if (@$ignore == false)
   {
      $sql = "select usr_id, ip from ad_count where usr_id = '$userid' AND ip = '$counter_ip'";
      $res = mysql_query($sql);
      if (mysql_num_rows($res) == 0)
      {
// Reloadsperre: IP und Zeit eintragen
	     $sql = "INSERT INTO ad_count (ad_id, usr_id, ip, visit) VALUES ('$ad_id', '$userid', '$counter_ip', NOW())";
   	     mysql_query($sql);
      }
      else
      {
         $ignore = true;
	     $sql = "update ad_count set visit = NOW(), ad_id = '$ad_id', usr_id = '$userid' where ip = '$counter_ip'";
	     mysql_query($sql);
		 exit();
      }
   }
   // Neue Statistikdaten
   if (@$ignore == false)
   {     	  
      // Tag
	  if ($day_id == date("z")) 
	  {
	     $day_value++; 
	  }
	  else 
	  {
	     $day_value = 1;
		 $day_id = date("z");
	  }
	  
	  // Woche
	  if ($week_id == date("W")) 
	  {
	     $week_value++; 
	  }
	  else 
	  { 
	     $week_value = 1;
		 $week_id = date("W");
      }
	  
      // Monat
	  if ($month_id == date("n")) 
	  {
	     $month_value++; 
	  }
	  else 
	  {
	     $month_value = 1;
		 $month_id = date("n");
      }
	  
	  // Jahr
	  if ($year_id == date("Y")) 
	  {
	     $year_value++; 
	  }
	  else 
	  {
	     $year_value = 1;
		 $year_id = date("Y");
      }
	  
	  // Alle
	  $all_value++;
		 
// Statistik aktualisieren
	  $sql = "update ad_stat set ad_id = '$ad_id', user_id = '$user_id', ad_kind = '$ad_kind', ad_ref = '$ad_ref', day_id = '$day_id', day_value = '$day_value', week_id = '$week_id', week_value = '$week_value', month_id = '$month_id', month_value = '$month_value', year_id = '$year_id', year_value = '$year_value', all_value = '$all_value' where ad_id = '$ad_id' AND day_id = '$today'";
	  mysql_query($sql); 
	  }  
?>
 
Ich kann mir kaum vorstellen, dass das über Dateien zu machen Performance sparender wäre, da dann ja entsprechend das FileSystem am rackern is ^^

Bleib da lieber bei SQL, is leichter mit zu arbeiten...
Bezüglich deines Performance Problems wurde ich erst kürzlich auf was gestossen...
Prepared Statements...
MySQLi !

Dürfte das ganze etwas beschleunigen...

Evtl sparste dir auch noch Code, vllt sogar etwas Performance, wenn du dass ganze dann als OOP aufbaust...
 
Diesen Teil hier:
PHP:
   $cid = $row['day_id'];
   $day_id = $row['day_id'];
   $day_value = $row['day_value'];
   $week_id = $row['week_id'];
   $week_value = $row['week_value'];
   $month_id = $row['month_id'];
   $month_value = $row['month_value'];
   $year_id = $row['year_id'];
   $year_value = $row['year_value'];
   $all_value = $row['all_value'];
   $record_date = $row['record_date'];
   $record_value = $row['record_value'];
könntest du eigendlich weglassen. Oder?
 
Diesen Teil hier:
PHP:
   $cid = $row['day_id'];
   $day_id = $row['day_id'];
   $day_value = $row['day_value'];
   $week_id = $row['week_id'];
   $week_value = $row['week_value'];
   $month_id = $row['month_id'];
   $month_value = $row['month_value'];
   $year_id = $row['year_id'];
   $year_value = $row['year_value'];
   $all_value = $row['all_value'];
   $record_date = $row['record_date'];
   $record_value = $row['record_value'];
könntest du eigendlich weglassen. Oder?

Nein, es muss ja geprüft werden ob für das Werbemittel an diesem Tag schon eine Statistik aufgestellt wurde oder nicht und wo der Counter erhöht wird falls Daten verfügbar sind.

@Chaosengel_Gabriel: Danke für den Tipp das werde ich mir mal genauer anschauen.

Bin aber weiter für Vorschläge offen, vll hatte ja schon jemand ein Problem dieser Art und hat es gut gelöst.
 
Du überschreibst niergend wo das Array $row, also kannst du die Variablen auch so direkt ansprechen und musst sie nicht unbedingt in seperate Variablen klatschen...

Ich glaub aber das spart eher bytes im Skript als Performance ^^
 
Ist nur ziemlich sinnfrei die einzelnen $row Elemente in extra Variablen zu schreiben. Das würde nur Sinn machen wenn man später im Skript $row überschreibt.
Und wieso sollte das der Performance nicht nützen? Das sind zwar minimale Rechenvorgänge, aber man sollte an Code sparen wo es geht.

Wie sagt man so schön neudeutsch: Just my 2 cents? :)
 
Ist nur ziemlich sinnfrei die einzelnen $row Elemente in extra Variablen zu schreiben. Das würde nur Sinn machen wenn man später im Skript $row überschreibt.
Und wieso sollte das der Performance nicht nützen? Das sind zwar minimale Rechenvorgänge, aber man sollte an Code sparen wo es geht.

Wie sagt man so schön neudeutsch: Just my 2 cents? :)

Klar das stimmt, werde ich direkt mal ändern. Habt ihr vll einen Lesetipp zum Thema "Optimierung von MySQL Queries"? Es gibt zwar sauviel zu diesem Thema, aber eine persönliche Empfehlung wäre echt sehr nett :)
 
Super, genau sowas hab ich gesucht :)

@all: nochmal vielen Dank! Habe die Statistik jetzt nochmal komplett überdacht und werde es via MySQLi regeln. Das macht bei einem AdServer wirklich Sinn.

greets
 
Zurück