Mysql Updates beschleunigen

Thomas_Jung

Erfahrenes Mitglied
Hallo

Diese Abfrage benötigt ca.5 Minuten.

PHP:
$sql = "SELECT lager,regal,hoehe,fach
FROM `weilhammer_datenbank`
WHERE lager = 3 AND 
(`status` =1 OR `status` =2 )
AND (`regal` !=0  AND `hoehe` !=0 AND `fach` !=0)
  LIMIT 0,1000
";

$query = mysql_query($sql);
while( $row = mysql_fetch_array( $query ) ) {

$update = "UPDATE `weilhammer_datenbank_lager` SET lrhf = '".$row['lager'].$row['regal'].$row['hoehe'].$row['fach']."' WHERE lager = '".$row['lager']."' AND regal = '".$row['regal']."' AND hoehe = '".$row['hoehe']."' AND fach = '".$row['fach']."'";
mysql_query($update );

}

Ich habe in der Tabelle weilhammer_datenbank und in der Tabelle weilhammer_datenbank_lager
jeweils für die Felder lager,regal hoehe,fach einen Index angelegt.

Indexname: lager
Indextyp: INDEX

Indexname: regal
Indextyp: INDEX

Indexname: hoehe
Indextyp: INDEX

Indexname: fach
Indextyp: INDEX

Meine Frage ist.


Kann ich diese Abfrage deutlich beschleunigen.

Gruß Thomas
 
Als erstes: PHP SQL-Statement in PHP lesbar darstellen

Dann würde man auch eher erkennen was da gehen sollte.

Deine Selektion vereinfacht:
SQL:
SELECT 
    lager,
    regal,
    hoehe,
    fach
FROM 
    weilhammer_datenbank
WHERE 
    lager = 3 
    AND `status` IN(1 , 2)
    AND regal !=0  
    AND hoehe !=0 
    AND fach !=0
-- Brauchst du den LIMIT wirklich?
LIMIT
    0,1000
Und dein Update
SQL:
UPDATE 
    weilhammer_datenbank_lager AS l
SET 
    l.lrhf = '{$row['lager']}{$row['regal']}{$row['hoehe']}{$row['fach']}' 
WHERE
    l.lager = '{$row['lager']}' 
    AND l.regal = '{$row['regal']}' 
    AND l.hoehe = '{$row['hoehe']}' 
    AND l.fach = '{$row['fach']}'

Alle Felder die du updatest hast du in der _lager Tabelle ja bereits vorhanden. Wozu noch den SELECT?
SQL:
UPDATE 
    weilhammer_datenbank_lager AS l
SET 
    l.lrhf = CONCAT(l.lager, l.regal, l.hoehe, l.fach)

Wenn es jetzt darum geht dass nur die ersten 1000 der weilhammer_datenbank Tabelle genommen werden sollten:
SQL:
UPDATE 
    weilhammer_datenbank_lager l
SET 
    l.lrhf = CONCAT(l.lager, l.regal, l.hoehe, l.fach) 
WHERE
    (l.lager, l.regal, l.hoehe, l.fach) IN (
        SELECT 
            lager,
            regal,
            hoehe,
            fach
        FROM 
            weilhammer_datenbank
        WHERE 
            lager = 3 
            AND `status` IN(1 , 2)
            AND regal !=0  
            AND hoehe !=0 
            AND fach !=0
        LIMIT
            0,1000
    )
Auf alle Fälle musst du nicht pro Zeile (Where-Schleife) einen Update senden. Das macht schon mal viel aus
 
Zuletzt bearbeitet von einem Moderator:
Hi Yaslaw

Deine Abfrage ist um 4 minuten schneller als meine. :)

Meine Aufgabe ist.

Ich habe 2 Tabellen eine ist die "datenbank" mit bereits gefüllten Datensätzen.

Felder: status, lager, regal, hoehe, fach
Inhalt: status = 1, lager = 1, regal = 1, hoehe = 1, fach = 3
Inhalt: status = 3, lager = 1, regal = 1, hoehe = 1, fach = 4
Inhalt: status = 1, lager = 1, regal = 1, hoehe = 1, fach = 5
u.s.w



Die zweite Tabelle ist das lager.

Felder: lrhf, lager, regal, hoehe, fach

Inhalt: lrhf = '', lager = 1, regal = 1, hoehe = 1, fach = 1
Inhalt: lrhf = '', lager = 1, regal = 1, hoehe = 1, fach = 2
Inhalt: lrhf = '', lager = 1, regal = 1, hoehe = 1, fach = 3

Inhalt: lrhf = '', lager = 1, regal = 1, hoehe = 1, fach = 4
Inhalt: lrhf = '', lager = 1, regal = 1, hoehe = 1, fach = 5
Inhalt: lrhf = '', lager = 1, regal = 1, hoehe = 1, fach = 6
u.s.w

Nun wollte ich ich den Inhalt lager,regal,hoehe,fach von der Tabelle "datenbank"
in das Feld "lrhf" der Tabelle "lager" einfügen.

Ziel ist es in der Tabelle "lager" leere "lrhf" anzuzeigen.

Was mit deiner Hilfe vom:
http://www.tutorials.de/php/394135-mysql-abfrage-leere-faecher-von-bis.html
auch Super funktioniert.


Nur der Abgleich der Tabellen dauer bei ca. 60.000 Datensätze in der Tabelle "datenbank" zu lange.

Gruß Thomas
 
Ich kenne mich bei MySQL und der Performance bei UPDATE WHERE IN nicht besonders gut aus. Aber evtl. ist ein JOIN schneller:
SQL:
			UPDATE weilhammer_datenbank_lager 
			SET 
				weilhammer_datenbank_lager.lrhf = CONCAT(Source.lager, Source.regal, Source.hoehe, Source.fach) 
			FROM 
			   (SELECT DISTINCT -- falls deine Werte eh distinct sind, kannst du dir das keyword auch sparen
					lager,
					regal,
					hoehe,
					fach
				FROM 
					weilhammer_datenbank
				WHERE 
					lager = 3 
					AND `status` IN(1 , 2)
					AND regal !=0  
					AND hoehe !=0 
					AND fach !=0
				-- gute Frage ob limit wirklich nötig ist ?! (ich denke mal nicht...)
				LIMIT
					0,1000) AS Source
			INNER JOIN
				weilhammer_datenbank_lager AS Target
			ON
					Target.lager = Source.lager
				AND Target.regal = Source.regal
				AND Target.hoehe = Source.hoehe
				AND Target.fach = Source.fach;
 
Zuletzt bearbeitet von einem Moderator:
UPDATE kennt kein FROM.
Wenn dann so zusammenfügen
SQL:
UPDATE items,month SET items.price=month.price
WHERE items.id=month.id;
Ob es mit einem Subselect innerhalb einer Quelle, geht weiss ich nicht auswendig
 
Zuletzt bearbeitet von einem Moderator:
Zurück