Script wird langsmer - evtl. Speicherproblem

Schrödi

Mitglied
Hi Leute,

ich habe ein Script geschrieben, das mir eine MySQL Abfrage in eine CSV Datei schreibt. Mein Problem ist, dass es sich hier um relativ viel Daten handelt (>400.000 Datensätze). Ein einfacher Scriptaufruf reicht hier zeitlich also nicht aus.

Also dachte ich mir: AJAX machts möglich.

Also habe ich mir ein Script gebastelt, das die Abfrage über das MySQL Limit nach und nach in die Datei schreibt. Funktioniert auch alles wunderbar, nur wird das Script nach jedem Aufruf durch Javascript immer langsamer. Ich habe auch immer daran gedacht alle Variablen wieder feizugeben unnd auch das MySQl result wieder freizugeben. Hilft alles nichts.

Habe ich irgendwas übersehen? Gibt es Ideen?


PHP:
$sql = $_SESSION['sql']." LIMIT ".$_SESSION['from'].", ".$_SESSION['step'];

$result= mysql_query($_SESSION['sql']);

$y=mysql_num_rows($result);
$k=mysql_num_fields($result);
for($i=0;$i<$y;$i++){
	for($j=0;$j<$k;$j++){
		$_SESSION['data'] .= '"'.mysql_result($result,$i,mysql_field_name($result,$j)).'";';
	}
	$_SESSION['data'] .=  "\r\n";
}
mysql_free_result($result);
mysql_close();
unset($result);


//In Datei Speichern
$_SESSION['step_num']++;
if($_SESSION['step_num'] % 10 == 0){
	$fp = fopen("../../".$_SESSION['file'],'a');
	fputs($fp, $_SESSION['data']);
	fclose($fp);
	
	unset($fp);
	unset($_SESSION['data']);
	$_SESSION['data']='';
}


if($_SESSION['from'] == 0)		$percent = 0;
else							$percent = ceil($_SESSION['from'] / $_SESSION['num_rows'] * 100);

$_SESSION['from'] += $_SESSION['step'];

if($_SESSION['from'] < $_SESSION['num_rows']){
	echo "Bitte warten ".$percent."%";
	?>
	<script type="text/javascript">content('content/auswertung/rohdaten_berechnung.php');</script>
	<?php 
} else {
	$file = fopen("../../".$_SESSION['file'],'a');
	fputs($file, $_SESSION['data']);
	fclose($file);
	
	?>
	Abgeschlossen. <a target="about_blank" href="<?= $_SESSION['file']; ?>">Download</a>
	<?php
	unset($_SESSION);
}

?>

Ich lade das Script alle 1000 Datensätze nach und speichere die Datensätze stringmäßig in eine Sessionvariable. Alle 10000 Datensätze speichere die Sessionvariable in die Datei und resette dann die Variable.

Anfangs habe ich es auch direkt in die Datei geschrieben, da aber ab 100000 Datensätzen das speichern der Datei etwas länger dauert, habe ich das Script somit schon etwas beschleunigt.
Reicht aber trotzdem nicht.

Gruß Schrodi
 
Moin,

ich würde das mit dem Laden der Datei in den Speicher nicht unbedingt unterschreiben, habe zumindest viel gegenteiliges dazu gelesen.

Was aber sicher im Speicher ist, sind die Session-Variablen...probiere daher mal, diese etwas öfters als alle 10k in die Datei zu schreiben und zu leeren.
 
Mein Fehler. Ich hatte im Kopf dass [phpf]fwrite[/phpf] komplett einliest, anhängt und wieder schreibt. Er hängt mit "append" aber wirklich erst ab Dateiende an.

/edit: Ich hatte oben einen fehlerhaften Beitrag in Bezug auf das Einlesen der Datei in den Speicher gemacht... Der ist aufgrund eines Fehlklicks im Nirvana verschwunden.
 
Hi Leute,

erstmal danke für eure Antworten. Um das Problem etwas einzugrenzen, habe ich mal nach und nach alles auskommentiert und habe mit erstauenen festgestellt, dass das Speichern und Zwischenspeichern der Daten nicht die Bremse ist.

Nachdem ich nun nur die Daten aus der Datenbank hole ohne Sie abzuspeichern und das Script immer noch zunhehmend mit jedem Aufruf langsamer wird muss das Problem bei dem mysql_query() liegen.

Um die DB selber auszuschließen habe ich während eines Exports einen DB Monitor laufen gelassen. Die Abfragen werden von der Datenbank selbst zügig bearbeitet.

Ist es vielleicht möglich die mysql_query() Resource so zwischenzuspeichern bzw. nach dem Wiederaufruf des Scripts auf ein altes QueryResource zurückzugreifen bzw. zu reinitialisieren, sodass ich nicht bei jedem Scriptdurchlauf ein neuen mysql_query durchführen muss?

So könnte ich einfach alle 1000 zeilen das Script neuladen und bei der aktuellen Zeile fortfahren.

Gruß schrodi
 
Hi,

PHP Version 5.0.4 auf MS IIS 6.0.
Ein Workaround ohne Adminrechte auf dem Server gibts wahrscheinlich nicht. Ein Update auf eine aktuellere Version ist beantragt , kann aber noch dauern.

Aber ich habe schon mal einen geringen Erfolg durch Änderung der Funktion mysql_connect auf mysql_pconnect.
Mysql_unbuffered_query() hat leider nichts gebracht.

Gruß
 
Zuletzt bearbeitet von einem Moderator:
Mysqli ist nicht aktiviert.
Werde ich aber nach durchgeführtem Update gleich berichtigen lassen.

Es ist absoluter Mist, wenn man nicht Herr über den Server ist.
 
Zurück