Abfrage an DB-Server dauert zu lang

Muss aber, zumindest muss es etwas geben, was die Sache ausbremmst. Sonst würde ja das selbe Script auf beiden Server in 2 Sekunden laufen. Und nicht der Externe mit 90 Sekunden. ;) Also muss es da ein Problem geben.
 
Das sehe ich auch so. Gibt es evtl. weitere Aktionen nach den MySQL-Statements? Was macht das Script den sonst noch irgendwelche Dinge? Besonders Netzwerk-Aktionen?
 
Vlt. wäre es hilfreich (falls nicht zu komplex / lang), das Script hier zu posten.
 
Zuletzt bearbeitet:
Für den nachfolgenden Code, benötigt das System rund 46 Sekunden. Was absolut nicht sein kann.

PHP:
// Kampagnen laden
	// Erstelle Liste aller laufender Kampagnen
	$CamIDs=array();
	$sql=mysql_query("SELECT CampaignID, DaysOfWeek, HoursOfDay, CompanionSharing, ImpressionsGuaranteed,ImpressionsDelivered,ClicksGuaranteed,ClicksDelivered,ImpCap,ImpCapInterval,ImpCapType,XMLTimestamp FROM Campaigns WHERE Status='Active' and StartDate<='".date("ymd")."' and EndDate>='".date("ymd")."'");
	while($CaOut=mysql_fetch_array($sql)){
		/* ### Starte zusätzliche Kampagnen-Prüfung ###
		* 1. Darf ich an diesem Tag ausliefern
		* 2. Darf ich um diese Stunde ausliefern
		* 3. Ist noch Volumen vorhanden (Prüfung von Einblendungen und Klicks)
		*/
		if(CheckDay($CaOut[DaysOfWeek])&&CheckHour($CaOut[HoursOfDay])&&CheckGuaranteed($CaOut[ImpressionsGuaranteed],$CaOut[ImpressionsDelivered])&&CheckGuaranteed($CaOut[ClicksGuaranteed],$CaOut[ClicksDelivered])):
			// Kampagnen IDs in ein Array packen.
			$CamIDs[]=$CaOut[CampaignID];

			// Delivery Array für diese Kampagne erzeugen.
			$Delevery[$CaOut[CampaignID]]=array();

			// Targeting (Regeln) einlesen
			$Rsql=mysql_query("SELECT JGender,JAgeFrom,JAgeTo,JRegio,JKeyWords,GRegio,GCountries,GCitys,SDisplay,SSystem,SBrowser,ISence FROM DeliveryControls WHERE CampaignID='".$CaOut[CampaignID]."'");
			if($CaRuOut=mysql_fetch_array($Rsql)){
				$Delevery[$CaOut[CampaignID]][CampaignRules]=array($CaOut[CampaignID],$CaRuOut[JGender],$CaRuOut[JAgeFrom],$CaRuOut[JAgeTo],$CaRuOut[JRegio],$CaRuOut[JKeyWords],$CaRuOut[GRegio],$CaRuOut[GCountries],$CaRuOut[GCitys],$CaRuOut[SDisplay],$CaRuOut[SSystem],$CaRuOut[SBrowser],$CaRuOut[ISence]);
			}

			// Doppelauslieferung filtern und steuern
			if($CaOut[CompanionSharing]=="N"||!$CaOut[CompanionSharing]){$CompanionSharing=$CaOut[CampaignID];}
			else{$CompanionSharing=0;}

			$Delevery[$CaOut[CampaignID]][CS]=array($CompanionSharing);

			// Auf FC prüfen
			if($CaOut[ImpCap]){
				$Delevery[$CaOut[CampaignID]][FC]=array($CaOut[ImpCap],$CaOut[ImpCapInterval],$CaOut[ImpCapType],$CaOut[CompanionSharing]);
			}

			// Zuordnung der Kampagne einlesen
			$Asql=mysql_query("SELECT SectionID,Type FROM CampaignAssignments WHERE CampaignID='".$CaOut[CampaignID]."'");
			while(list($SectionID,$Type)=mysql_fetch_row($Asql)){
				if(isset($SecArray[$Type][0])){array_push($SecArray[$Type],$SectionID);}
				#BuildAssigments($SectionID);
			}
			if($SecArray):
				$Delevery[$CaOut[CampaignID]][CampaignAssiments]=$SecArray;
			endif;
			$SecArray='';

			// Temp array für SHM $SHMTemp
			$ReloadTemp[$CaOut[CampaignID]]=array();
		endif;
	}

Wie du siehst, nur lari fari berechnungen.
 
Nichts besonderes, also keine großen Kalkulationen:

PHP:
function CheckDay($DaysOfWeek){
	// Tag der Auslieferung prüfen
	if($DaysOfWeek<127):
		$Day=$DaysOfWeek;
		$setarray=array();
		$arrayday=array("64","32","16","8","4","2","1");
		for($i=0;$i<7;$i++){
			$DayNew=$Day+$arrayday[$i];
			if($DayNew<=127){
				$Day=$DayNew;
				array_push($setarray,$arrayday[$i]);
			}
		}

		$DayNowForArray=6-date("w");
		if(!in_array($arrayday[$DayNowForArray],$setarray)):
			return 1;
		else:
			return 0;
		endif;
	else:
		return 1;
	endif;
}

Wie schon gesagt, dass ist nichts was den Server belastet. Sind ja die selben mit den identischen einstellungen. Und lokal macht der diese Schleife in weniger als 2 Sekunden extern brauch das System rund 45 Sekunden. Muss also irgend was zwischen den Servern nicht stimmen. Vielleicht ein paar Einstellungen oder so was?
 
Vielleicht ein paar Einstellungen oder so was?

Mit Sicherheit ist das nur eine Konfigurationssache. Die Frage ist nur, welche Regler man drehen muss. Daher auch die Detail-Analyse.

Wir fassen noch mal kurz zusammen:

Das Script benötigt
- auf DBSERV 2 Sekunden
- auf WEBSERV > 2*10 Sekunden (der tatsächliche Wert variiert offensichtlich)
- die einzelnen Queries benötigen auf WEBSERV auch nur Millisekunden

Es gibt noch keinen Anhaltspunkt, was das Performance-Leck verursacht.

Du hast jetzt mehrere Möglichkeiten:

1. Du baust vor und hinter alle möglichen Calls ein microtime() für eine detailiertere Zeitmessung, dadurch erfährst du, welcher Call es genau ist, den könnte man dann analysieren.

2. Du benutzt auf WEBSERV die Extension xdebug und stellst da den Profiler ein. Das führt dich zum gleichen Ergebnis wie 1. aber du musst den Code nich anfassen (es spart Zeit). Du wendest auf das Profile-Out irgendein *cachegrind-Tool an um den Performance-Engpass visualisiert zu finden.

3. Du traced mittels tcpdump den Netzwerk-Traffic mit und leidest die Ausgabe in eine Datei um. Diese kannst du mit Wireshark oder Ethereal öffnen und schauen, wie sich das Anfrage-Antwort-Verhalten ... ähm verhält.

Noch irgendjemand Ideen für die Analyse?

Momentan ist es noch stochern im Nebel.
 
OK, werde das morgen meiner Technik geben, die sollen das mal installieren und eine Analyse laufen lassen. Die Analyse kommt dann hier natürlich rein. ^^
 
Zurück