tutorials.de Buch-Aktion 05/2012
Seite 1 von 2 12 LetzteLetzte
ERLEDIGT
JA
ANTWORTEN
21
ZUGRIFFE
1561
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    jannicars jannicars ist offline Mitglied Gold
    Registriert seit
    Jun 2011
    Beiträge
    219
    Hallo,

    Ich habe derzeit ein Projekt am laufen, wo ich jede Nacht um 1:00 Uhr
    Daten aus XML Files beziehe.
    Im Moment sind knapp 5.000 Einträge vorhanden.
    100 Einträge = 11 Sek.
    1.000 Einträge = 110 Sek.
    5.000 Einträge = 550 Sek.
    550 % 60 = ~9 Minuten
    Ausgenommen immer ein DB Update.
    Also sagen wir mal, dass dauert 10 Minuten.

    Wenn ich jetzt 50.000 Einträge hätte, würde das ganze 100 Minuten dauern.
    Nun dachte ich mir, währe es doch theoretisch möglich 10 Files gleichzeitig zu beziehen,
    würde das ganze um dem Faktor 10 beschleunigen.

    Diese pcntl_fork Geschichte scheint wohl nicht das wahre zu sein,
    da ich mir da wahrscheinlich schon ein eigenes Framework(zumindest eine umfangreiche Klasse) basteln müsste.

    So nun meine Frage:
    Hätte jemand eine Idee wie man dies schneller und effektiver lösen kann?
     

  2. #2
    Avatar von javaDeveloper2011
    javaDeveloper2011 javaDeveloper2011 ist gerade online Mitglied Brokat
    Registriert seit
    Feb 2011
    Beiträge
    445
    Blog-Einträge
    5
    Hi jannicars,

    ich würde mal ganz schlicht sagen: PHP hat nicht wirklich Threading, und einfach so "herzaubern" kann man das auch nicht.
    Sind die Aktionen kompliziert?
    Ist die Beschleunigung (sehr) wichtig?
    Du könntest auch einfach ein "normales" Programm, z.B. in C++ schreiben und dann aus PHP heraus aufrufen.

    Gruß
     

  3. #3
    Registriert seit
    Jun 2002
    Ort
    Saarbrücken (Saarland)
    Beiträge
    9.886
    Blog-Einträge
    29
    Hallo,

    eine weitere einfache alternative... wenn die Import-Vorgänge alle unabhängig voneinander sind, dann starte doch einfach X PHP-Prozesse zur Verarbeitung deiner Dateien mit unterschiedlicher Parameterisierung (Prozess 1: Files 0-1000, Prozess 2: Files: 1001-2000, etc.).

    Gruß Tom
     
    Java rocks!
    How to become a good Java Programmer?
    Does IT in Java and .Net
    The only valid measurement of code quality: WTFs / minute
    Blog
    Xing
    Twitter

  4. #4
    jannicars jannicars ist offline Mitglied Gold
    Registriert seit
    Jun 2011
    Beiträge
    219
    Hi javaDeveloper2011,

    Die Beschleunigung des Scriptes ist sehr wichtig,
    da dass Script mit 5.000 Einträgen knapp 1 Stunde braucht.
    Es werden bestimmt bald locker sich um die 50.000 Einträge in der
    Datenbank rumtummeln.
    Das Problem an der anderen Sprache währe,
    1. Ich kann keine andere Sprache.
    2. Ich benutze ein Framework in PHP(bestimmt könnte es auch ohne gehen, wird dann aber wieder komplizierter.)

    So umfangreich ist das ganze Script auch nicht:
    1. Schritt-> Alle Einträge in eine Schleife packen
    2. Schritt-> In der Schleife dann das File immer einzeln laden, Daten entnehmen,
    ein MySQL Datenbank update (1 Eintrag editieren) und in eine andere Tabelle 1 Insert.
    Schritt 2 Halt immmer in einer Schleife.



    Zitat Zitat von Thomas Darimont Beitrag anzeigen
    Hallo,

    eine weitere einfache alternative... wenn die Import-Vorgänge alle unabhängig voneinander sind, dann starte doch einfach X PHP-Prozesse zur Verarbeitung deiner Dateien mit unterschiedlicher Parameterisierung (Prozess 1: Files 0-1000, Prozess 2: Files: 1001-2000, etc.).

    Gruß Tom
    Darüber habe ich mir auch schonmal Gedanken gemacht.
    Mein gedachter Weg dies zu realisieren:
    1. Alle Einträge zählen und in 10-20 Prozesse aufteilen.
    2. per Exec() die Datei aufrufen mit GET(?!) Parametern.
    3. Den Rest halt da weiterlaufen lassen.

    Klingt irgendwie ganz gut.
    Geändert von jannicars (30.01.12 um 17:05 Uhr)
     

  5. #5
    bergonline bergonline ist offline Mitglied Platin
    Registriert seit
    Jul 2006
    Beiträge
    518
    Hey,

    wie ist dein Import-Vorgang gelöst bzw. programmiert?
    Vielleicht gibt es dort noch Potenzial ...

    mfg
    bo
     

  6. #6
    Avatar von ComFreek
    ComFreek ComFreek ist offline [x] Let it be logic!
    tutorials.de Moderator
    Registriert seit
    Jun 2009
    Beiträge
    2.359
    Blog-Einträge
    4
    So umfangreich ist das ganze Script auch nicht:
    1. Schritt-> Alle Einträge in eine Schleife packen
    2. Schritt-> In der Schleife dann das File immer einzeln laden, Daten entnehmen,
    ein MySQL Datenbank update (1 Eintrag editieren) und in eine andere Tabelle 1 Insert.
    Schritt 2 Halt immmer in einer Schleife.
    Wie wäre es, wenn du zuerst alle SQL-Statements sammelst und sie dann gemeinsam auf einen Schlag ausführst?

    2. per Exec() die Datei aufrufen mit GET(?!) Parametern.
    Rufe es lieber mit Parametern auf:
    Code :
    1
    
    php -f /path/to/the/file.php firstparam secondparam

    Und im PHP-Skript kannst du per $argv auf die Paramter zugreifen.
     
    mfg ComFreek

    Falls ich dir geholfen habe, würde ich mich über ein DANKE freuen!
    Kenn mich am besten aus in C++, WEB-Sprachen (PHP, HTML, JavaScript) und vllt. mehr
    [PHP] Überprüfen, ob Website erreichbarSicherheit in PHP-Codes schaffenGoogle Chrome-Extension für tutorials.dejson_compress()

  7. #7
    jannicars jannicars ist offline Mitglied Gold
    Registriert seit
    Jun 2011
    Beiträge
    219
    Zitat Zitat von ComFreek Beitrag anzeigen
    Wie wäre es, wenn du zuerst alle SQL-Statements sammelst und sie dann gemeinsam auf einen Schlag ausführst?
    Würde das so drastisch den ganzen Ablauf beschleunigen?
    Aber dafür braucht das Script mehr RAM?

    Zitat Zitat von ComFreek Beitrag anzeigen

    Rufe es lieber mit Parametern auf:
    Code :
    1
    
    php -f /path/to/the/file.php firstparam secondparam

    Und im PHP-Skript kannst du per $argv auf die Paramter zugreifen.
    Ich hab früher auch schon versucht, Scripte per command line auszuführen, scheiterte immer beim includen von anderen Dateien.
    Ich hab da glaub ich immer
    Code :
    1
    
    php -c oder -x
    benutzt.
     

  8. #8
    Avatar von ComFreek
    ComFreek ComFreek ist offline [x] Let it be logic!
    tutorials.de Moderator
    Registriert seit
    Jun 2009
    Beiträge
    2.359
    Blog-Einträge
    4
    Würde das so drastisch den ganzen Ablauf beschleunigen?
    Aber dafür braucht das Script mehr RAM?
    Habe gerade schnell mal einen Test gemacht:

    Tabelle:
    Code sql:
    1
    
    CREATE TABLE big_table ( id INTEGER AUTO_INCREMENT PRIMARY KEY, sometext CHAR(255) )

    Es werden jeweils 1000 255 Zeichen lange Strings eingefügt:
    1.) mysqli_query() bei jedem Durchlauf der Schleife (Zeitdifferenz in Mikrosekunden | RAM in Bytes):
    1.8684060573578 | 331760
    2.) mysqli_query() außerhalb der Schleife mit 1000 INSERT VALUES-Kommandos:
    0.075608015060425 | 592648
    Also, es lohnt sich auf jeden Fall. Wenn du dann noch ein mysqli_query()-Kommando nach jedem x. Hinzufügen von Werten einbaust, kannst du auch noch die RAM-Nutzung regulieren.
    Ich hab früher auch schon versucht, Scripte per command line auszuführen, scheiterte immer beim includen von anderen Dateien.
    set_include_path() könnte dir helfen.
     
    mfg ComFreek

    Falls ich dir geholfen habe, würde ich mich über ein DANKE freuen!
    Kenn mich am besten aus in C++, WEB-Sprachen (PHP, HTML, JavaScript) und vllt. mehr
    [PHP] Überprüfen, ob Website erreichbarSicherheit in PHP-Codes schaffenGoogle Chrome-Extension für tutorials.dejson_compress()

  9. #9
    jannicars jannicars ist offline Mitglied Gold
    Registriert seit
    Jun 2011
    Beiträge
    219
    Also einfach in der Schleife alles in ein Array packen,
    am schluss das ganze Array in einer For Schleife mit Insert und Update machen in einem Rutsch?

    Könntest du am besten mal das Testscript posten?
     

  10. #10
    Avatar von Lime
    Lime Lime ist offline frisch fruchtig
    Registriert seit
    Jul 2011
    Beiträge
    369
    Zitat Zitat von jannicars Beitrag anzeigen
    Also einfach in der Schleife alles in ein Array packen,
    am schluss das ganze Array in einer For Schleife mit Insert und Update machen in einem Rutsch?

    Könntest du am besten mal das Testscript posten?
    Dann führst du immer noch jedes SQL-Statement einzeln aus.
    Du sollst die Statements zusammenhängen...

    Code sql:
    1
    
    INSERT INTO TABLE (id) VALUES (12);INSERT INTO TABLE (id) VALUES (12);INSERT INTO TABLE (id) VALUES (12)
     

  11. #11
    Avatar von ComFreek
    ComFreek ComFreek ist offline [x] Let it be logic!
    tutorials.de Moderator
    Registriert seit
    Jun 2009
    Beiträge
    2.359
    Blog-Einträge
    4
    Einfach per Kommata die einzelnen Werte-Blöcke (in Klammern) trennen.
    Mein Test-Code war:


    test1.php:
    PHP-Code:
    <?php

    $connection 
    mysqli_connect('***','***','***','***') or die('ERROR');

    $text str_repeat('ABCDE'51);
    $limit 1000;

    $time1 = array(microtime(true));
    for ( 
    $i=0$i<$limit$i++ )
    {
      
    mysqli_query($connection'INSERT INTO big_table (sometext) VALUES (\''.$text.'\')') or die(mysqli_error($connection));
    }
    $time1[] = microtime(true);

    echo 
    $time1[1]-$time1[0] . '|' memory_get_usage();

    ?>
    test2.php:
    PHP-Code:
    <?php

    $connection 
    mysqli_connect('***','***','***','***') or die('ERROR');

    $text str_repeat('ABCDE'51);
    $limit 1000;

    $time2 = array(microtime(true));
    $queries 'INSERT INTO big_table (sometext) VALUES (\''.$text.'\')';
    for ( 
    $i=0$i<$limit$i++ )
    {
      
    $queries .= ',(\''.$text.'\')';
    }
    mysqli_query($connection$queries) or die(mysqli_error($connection));
    $time2[] = microtime(true);

    echo 
    $time2[1]-$time2[0] . '|' memory_get_usage();


    ?>
    jannicars bedankt sich. 
    mfg ComFreek

    Falls ich dir geholfen habe, würde ich mich über ein DANKE freuen!
    Kenn mich am besten aus in C++, WEB-Sprachen (PHP, HTML, JavaScript) und vllt. mehr
    [PHP] Überprüfen, ob Website erreichbarSicherheit in PHP-Codes schaffenGoogle Chrome-Extension für tutorials.dejson_compress()

  12. #12
    jannicars jannicars ist offline Mitglied Gold
    Registriert seit
    Jun 2011
    Beiträge
    219
    Danke!
    Das werd ich auf jedenfall so umsetzen.
    Werde auch noch gucken, ob ich das mit dem Aufteilen vernünftig realisiert bekomme.
     

  13. #13
    jannicars jannicars ist offline Mitglied Gold
    Registriert seit
    Jun 2011
    Beiträge
    219
    Die Sache mit dem Aufteilen:
    20 PHP Prozesse sind doch für einen schnellen Server kein Problem, da dass ja nichts rechtenintensives ist, oder?
    Auch wenn ich das wie obig beschrieben mache; erst alle sammeln dann Updaten; dürfte den MySQl Server nicht in die Knie ziehen oder?
     

  14. #14
    Avatar von Lime
    Lime Lime ist offline frisch fruchtig
    Registriert seit
    Jul 2011
    Beiträge
    369
    Sollte es nicht, nein...
    Allerdings ist es eine gute Frage, ob es nicht gescheiter wäre 5 Mal je 4Prozesse laufen zu lassen, wenn du eh alle SQL-Querys auf einmal durchführst, indem du sie vorher sammelst. Das dürfte doch schneller gehen und spart Ressourcen. Probier einfach bisschen rum...
     

  15. #15
    jannicars jannicars ist offline Mitglied Gold
    Registriert seit
    Jun 2011
    Beiträge
    219
    Dann hab ich ja diese Woche nie langeweile.. Danke
     

Ähnliche Themen

  1. Multithreading
    Von bspainkf36 im Forum Java
    Antworten: 4
    Letzter Beitrag: 11.10.09, 17:00
  2. Multithreading
    Von Paranoia im Forum .NET Web und Kommunikation
    Antworten: 1
    Letzter Beitrag: 24.06.08, 17:32
  3. Multithreading
    Von pria im Forum .NET Windows Forms
    Antworten: 10
    Letzter Beitrag: 09.11.07, 11:42
  4. Multithreading
    Von Kaladial im Forum Java
    Antworten: 10
    Letzter Beitrag: 20.09.07, 13:40
  5. [c++] multithreading
    Von cyrrus im Forum C/C++
    Antworten: 6
    Letzter Beitrag: 01.11.02, 20:08