Ankündigung

Einklappen
Keine Ankündigung bisher.

PHP Skript Optimierung - MySQL + CSV

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • PHP Skript Optimierung - MySQL + CSV

    Hallo,

    ich habe hier ein Skript, dass mir zunächste eine CSV Datei einliest mit ca. 135000 Zeilen und ca. 23 Spalten. Aufgrund dessen mußte ich schon das Memory_limit auf 512 MB setzen.
    Von dieser CSV Datei benötige ich eigentlich nur 2 Spalten, nämlich die Bestellnummer(langtext2) und den Lagerbestand.

    Anhand einer MYSQL Tabelle wir nun verglichen wo die Bestellnummer mit der Nummer in der CSV Datei übereinstimmt und der passende Bestandswert in die MYSQL Tabelle übernommen.

    Die MYSQL Tabelle enthält ca 3000 Zeilen. Selbst bei einer max_execution_time von 2000 wird das Skript nicht fertig.

    Wo kann ich optimieren um das Ausführen zu beschleunigen?
    Die Ausführung des Einlesens der CSV Datei dauert nur 13 Sekunden. Würde es etwas bringen, die nicht benötigten Spalten zu löschen oder macht das keinen Unterschied?

    Christian

    PHP-Code:
     <?php

    $beginn 
    microtime(true);
    @
    ini_set("memory_limit",'512M');
    @
    ini_set("max_execution_time",'2000');
    error_reporting(0);
    $dateizeiger fopen("Artikelliste.txt""r+");
    $zeilenzahl=0;
    $verbindung mysql_connect("localhost","root","") or die ("keine Verbindung möglich. Benutzername oder Passwort sind falsch");
    mysql_select_db("Artikel") or die ("Die Datenbank existiert nicht.");
    function 
    searchforid($id$myarray) {
       for (
    $row 0$row<135000$row++) {
        if (
    $myarray[$row][2]=== $id)    return $row;
          }
       
    //return "nix gefunden";
    }

    while((
    $daten fgetcsv($dateizeiger500"\t")) !== FALSE)
      {
          
    $spaltenzahl count($daten);     
          for(
    $i=0;$i<$spaltenzahl;$i++)
              {
                  
    $array[$zeilenzahl][$i]=$daten[$i];              
              }
        
    $zeilenzahl++;   
      }
    $dauer microtime(true) - $beginn
    echo 
    "Verarbeitung des Skripts: $dauer Sek.";
    $beginn1 microtime(true);  
    $abfrage "SELECT langtext2 FROM hilfs";
    $ergebnis mysql_query($abfrage);
    $hilfe1 0;
    while(
    $zeile mysql_fetch_object($ergebnis))
       {
       
    $suchstring=$zeile->langtext2;
       
    $hilfsvar=$array[searchforid($suchstring,$array)][6];
       
    $query2='UPDATE hilfs set bestand = "'.$hilfsvar.'" where langtext2 = "'.$suchstring.'" ';
       
    mysql_query($query2);
       
    $hilfe2=mysql_affected_rows();
       if (
    $hilfe2 <> "-1") {
       
    $hilfe1=$hilfe1+1;}
       
       
    printf(mysql_error());
       }

    printf("Geändert Datensätze: %d\n"$hilfe1);
    fclose($dateizeiger);
    echo(
    "<br>");
    $dauer microtime(true) - $beginn1
    echo 
    "Verarbeitung des Skripts: $dauer Sek.";
     
    ?>


  • #2
    Ich werf' einfach mal rein nach Gefühl Indizes für die MySQL-Tabelle in den Raum - hast du das schon erwogen/versucht?

    Kommentar


    • #3
      Mal kurz überflogen, wie der Programmablauf aussieht.

      - csv wird eingelesen und im Array abgelegt
      - Nacheinander werden die Datensätze aus der Datenbank gefetched
      - Für jeden Datenbankeintrag wird das Array aus der csv durchlaufen und geprüft ob die id stimmt
      - Falls ja erfolgt ein update


      Du könntest ja mal per implode aus den IDs von der csv deine Abfrage bauen, SELECT bla FROM tabelle WHERE id IN ('viele ids aus der csv');
      Dadurch würdest du das große Array nur einmal durchgehen, um den Query zu erstellen. Und nicht 3000 mal um die id zu suchen.

      Würde es etwas bringen, die nicht benötigten Spalten zu löschen oder macht das keinen Unterschied?
      Würde wohl den Speicherbedarf senken.


      Standardtext für die Datenbankverbindung:
      Die mysql_* Erweiterung ist veraltet und wird in der nächsten PHP-Version entfernt.
      Durch einen Wechsel auf mysqli_* oder PDO greifst du auf die modernere API zu und hast die Möglichkeiten Prepared Statements zu benutzen die gegen Injections schützen.
      Ich persönlich bevorzuge PDO, schönes Tutorial: http://www.peterkropff.de/site/php/pdo.htm
      Relax, you're doing fine.
      RTFM | php.de Wissenssammlung | Datenbankindizes | Dateien in der DB?

      Kommentar


      • #4
        Vielen Dank für die Anregungen:

        @monolith
        Ich habe kurz die Funktionsweise von Indizes überflogen. Mir erschließt sich nich nicht der Vorteil der Indizierung. Die Daten, die ich vergleiche sind über den Array verteilt. Was genau soll bei der Suche den Vorteil bringen?

        @VPH
        ist die Suche mit IN auf eine Menge begrenzt? Dort würden dann immerhin 3000 Datensätze drinstehen.
        Ich habe mit IN noch nicht gearbeitet. Wie kombiniere ich die SELECT Abfrage mit dem späteren UPDATE? Hab da gerade noch nicht den Durchblick und wohl ne Denkblockade

        Kommentar


        • #5
          Mit dem IN in der Art die ich meinte würde es wohl nicht funktionieren, gerade gesehen, dass du ja noch einen Wert aus der csv brauchst.

          Du könntest aber die csv in die Datenbank importieren. Per Datenbankabfrage mit IN und Subselect die IDs und Bestandsnummern holen und dann updaten.
          Relax, you're doing fine.
          RTFM | php.de Wissenssammlung | Datenbankindizes | Dateien in der DB?

          Kommentar


          • #6
            einen mehrdimensionalen array in eine Mysql tabelle einzulesen scheint wohl etwas komplizierter. Habe bisher kein fertiges Skript dafür gefunden. Irgendwelche nützlichen Links zur Hand?

            Kommentar


            • #7
              http://stackoverflow.com/questions/1...sing-php-mysql
              Relax, you're doing fine.
              RTFM | php.de Wissenssammlung | Datenbankindizes | Dateien in der DB?

              Kommentar

              Lädt...
              X