2012-04-13 3 views
1

Zur Zeit habe ich eine MySQL-Abfrage, die ich in PHP laufen und wenn Sie durch die Ergebnisse gehen ich die Original-Tabelle, sondern eine einfache Tabelle aktualisieren mit 500 Reihen 30 Sekunden dauert abzuschließen:Warum ist diese MySQL-Abfrage meinen Code zu verlangsamen

$sqlquery = mysql_query('SELECT id, special_data FROM stats_visits WHERE processed = 0'); 
while($row = mysql_fetch_assoc($sqlquery)){ 
    $stat_id = $row['id']; 
    // Make use of special_data field for some operations 
    mysql_query('UPDATE stats_visits SET processed = 1 WHERE id = ' . $stat_id); 
} 

Liegt es daran, dass ich die Tabelle aktualisiere, aus der ich mich auswähle? Ich habe dieses Problem gelöst, indem Sie folgendermaßen vorgehen, sondern weil die Tabelle Tausende von Datensätzen in der Zukunft haben könnte, ich bin nicht sicher, wie gut die IN halten wird:

$statids = array(); 

$sqlquery = mysql_query('SELECT id, special_data FROM stats_visits WHERE processed = 0'); 
while($row = mysql_fetch_assoc($sqlquery)){ 
    $statids[] = $row['id']; 
    // Make use of special_data field for some operations 
} 

mysql_query('UPDATE stats_visits SET processed = 1 WHERE id IN(' . implode(',', $statids) . ')'); 
+3

Warum werden alle Zeilen abgerufen und nach ID aktualisiert, anstatt nur basierend auf den Bedingungen, die Sie in SELECT verwendet haben, zu aktualisieren? – geoffspear

+0

In diesem wählen (ich hätte das wahrscheinlich angezeigt) Ich wähle mehr Daten, verwenden Sie es für die Verarbeitung und einmal verwendet, muss ich dies angeben, indem Sie verarbeitete = 1, so dass ich im nächsten Lauf kann es überspringen. – ChimeraTheory

+0

Wenn Sie nur die Spalte 'processed' aktualisieren, gibt es keinen Grund, eine 'SELECT'- und eine 'UPDATE'-Abfrage auszuführen. Sie können dies mit der unten angegebenen Antwort @Truth tun. Die andere Option besteht darin, ein Array von bearbeiteten Daten zu verwenden und alles in zwei Abfragen zu kombinieren. – gorelative

Antwort

2

In der ersten Version sind Sie die Datenbank einmal für jedes einzelne Update zu treffen. Dies ist normalerweise eine schlechte Idee. Die zweite Version trifft die Datenbank einmal.

Wenn Sie besorgt sind, wie dies in der Zukunft funktionieren wird, erstellen Sie vielleicht einen Hybrid. Stapeln Sie die Aktualisierungen in Gruppen von 100 Stück und aktualisieren Sie sie in Blöcken.

+0

Batch klingt wie eine gute Idee - implementiert es und funktioniert wie ein Charme und keine Sorge über Abfragen zu lange. Vielen Dank. – ChimeraTheory

6

Wenn alles, was Sie wollen, ist, um alle Datensätze zu aktualisieren sein processed = 1 Warum lösen sie nicht mit einer einzigen Abfrage ?:

UPDATE `stats_visits` SET `processed` = 1 WHERE `processed` = 0; 
+0

Da in diesem wählen (ich hätte das wahrscheinlich angezeigt) Ich wähle mehr Daten, verwenden Sie es für die Verarbeitung und einmal verwendet, muss ich dies durch Einstellung von verarbeiteten = 1 angeben, damit ich im nächsten Lauf kann ich es überspringen. – ChimeraTheory

+0

-1 Wenn er verarbeitet (wie oben angegeben), könnten Sie versehentlich Datensätze als verarbeitet markieren, die nicht tatsächlich verarbeitet werden. –

+0

in der OPs-Abfrage vor allem hes tun ist das Auswählen von Zeilen und dann diese Zeilen aktualisieren. Effektiv zu tun, was @Truth gesagt hat, ist dasselbe. Dies ist die richtige Antwort. Ihre andere Option ist es, diese "UPDATE" mit der "UPDATE" für Ihre "Verarbeitung" von "anderen Daten" zu kombinieren. – gorelative

1

Der einfachste Weg wäre, alle IDs zu speichern, die als Array aktualisiert werden müssen, und diese dann in die Abfrage mit dem Operator IN zu implodieren.

z.B.

+0

Das habe ich getan. – ChimeraTheory