504 Gateway Time-out - Bei einem Update Script
bearbeitet von
Hallo Thomas,
da du pro Produkt einen SELECT auf die Preise-Tabelle und einen UPDATE auf die Produkte Tabelle machst, ist es keine Kleinigkeit, was Du da treibst. 48047 separate SQL Zugriffe sind schon einiges, und wenn der SQL Server auch für andere Leute aktiv ist, kann das dauern. Du musst Dich ja mit jeder Query neu hinten in der Warteschlange anstellen :). Und - hast Du Indizes auf Preise.Nr und Produkte.ArtNr gelegt?
Wenn Du unbedingt jeden Preis im Programm verarbeiten musst - was nicht zwingend der Fall ist - dann könntest Du die Anzahl der Queries schon mal halbieren indem Du die Produkte mit EINER Query in eine eigene Tabelle lädst und dann dort die Preise heraussuchst.
Ob man mit mysqli so etwas wie einen Update-Cursor machen kann, weiß ich nicht; aber wenn ja, könntest Du die Produkte mit einem Update-Cursor durchlaufen und nicht für jeden Preis ein separates Update-Statement absetzen.
Du kannst für den Fall, dass ein Produkt keinen Eintrag in der Preise-Tabelle hat, auch auf den Update ganz verzichten.
Wenn mysqli->prepare so funktioniert wie ich das erwarte, dann musst Du auch nicht in jedem Schleifendurchlauf den prepare machen. Der dürfte Zeit kosten. Statt dessen kannst Du ihn vor die Schleife ziehen und in der Schleife nur den bind_param machen. Das ist meines Wissens der SINN von prepared Statements.
Ja, und dann wäre noch diese Variante:
~~~sql
UPDATE Produkte
SET Preis = COALESCE((SELECT Netto
FROM Preise
WHERE Preise.Nr = Produkte.ArtNr), Produkte.Preis)
~~~
Das ist eine einzige Query. Der innere SELECT liefert NULL wenn es zu einem Produkt keinen Preis gibt, und COALESCE liefert den ersten seiner Parameter zurück, der nicht NULL ist. Heißt: Gibt's einen Preis bei Preise, wird er übernommen, andernfalls der alte Preis beibehalten. Das wolltest Du doch, oder?
Gruß
Rolf
504 Gateway Time-out - Bei einem Update Script
bearbeitet von
Hallo Thomas,
da du pro Produkt einen SELECT auf die Preise-Tabelle und einen UPDATE auf die Produkte Tabelle machst, ist es keine Kleinigkeit, was Du da treibst. 48047 separate SQL Zugriffe sind schon einiges, und wenn der SQL Server auch für andere Leute aktiv ist, kann das dauern. Du musst Dich ja mit jeder Query neu hinten in der Warteschlange anstellen :)
Wenn Du unbedingt jeden Preis im Programm verarbeiten musst - was nicht zwingend der Fall ist - dann könntest Du die Anzahl der Queries schon mal halbieren indem Du die Produkte mit EINER Query in eine eigene Tabelle lädst und dann dort die Preise heraussuchst.
Ob man mit mysqli so etwas wie einen Update-Cursor machen kann, weiß ich nicht; aber wenn ja, könntest Du die Produkte mit einem Update-Cursor durchlaufen und nicht für jeden Preis ein separates Update-Statement absetzen.
Du kannst für den Fall, dass ein Produkt keinen Eintrag in der Preise-Tabelle hat, auch auf den Update ganz verzichten.
Wenn mysqli->prepare so funktioniert wie ich das erwarte, dann musst Du auch nicht in jedem Schleifendurchlauf den prepare machen. Der dürfte Zeit kosten. Statt dessen kannst Du ihn vor die Schleife ziehen und in der Schleife nur den bind_param machen. Das ist meines Wissens der SINN von prepared Statements.
Ja, und dann wäre noch diese Variante:
~~~sql
UPDATE Produkte
SET Preis = COALESCE((SELECT Netto
FROM Preise
WHERE Preise.Nr = Produkte.ArtNr), Produkte.Preis)
~~~
Das ist eine einzige Query. Der innere SELECT liefert NULL wenn es zu einem Produkt keinen Preis gibt, und COALESCE liefert den ersten seiner Parameter zurück, der nicht NULL ist. Heißt: Gibt's einen Preis bei Preise, wird er übernommen, andernfalls der alte Preis beibehalten. Das wolltest Du doch, oder?
Gruß
Rolf