Script bricht nach ca. 6-7 Minuten ab

  • Also folgendes: Ich hab ein Script das eine Datei einließt und den inhalt mit daten aus einer datenbank vergleicht. (effektiv werden sha1 gehashete mails aus einer datei mit mails aus einer db nach übereinstimmung geprüft). Nur handelt es sich bei der Datei um ca. 19.000+ Einträge und wird vergelicht mit mehr als 10.000 Mails. Da ergeben sich 190.000.000 abfragen und das kann sich schon ein paar minuten hinziehen. Alles fein nur bei sehr langen abfragen, also bei so in etwa welche die länger als 6-7 min. ergeben sich folgende fehler:

    • im IE hört das script einfach nicht mehr auf
    • im FF2 kommt plötzlich ein download popup mit der frage ob ich die php datei (die gerade ausgeführt wird) herunterladen will. Die Datei is aber dann leer.

    Folgendes hab ich schon gemacht/versucht:

    • set_time_limit() auf über 30 minuten gestellt
    • Die SQL abfragen so geschachtelt das immer nur max 5000 auf einmal durchlaufen wird, danach die connection geschlossen und bei den nächsten 5000 wird geöffnet wird. Grund: ich dachte das die sql db nach ein paar minuten vergisst das sie was zum tun hat oder den login vergisst.
    • hab versucht nach allen 10.000.000 abfragen ein echo "."; an den browser zu schicken weil ich gelesen hab dass der browser einfach mal aufhört wenn er kein response bekommt - half aber nix.

    Bin aber jetzt ratlos - hab auch sonst nichts nützliches gefunden - bin für jeden tipp dankbar.
    (PS der Server unterstütz nur PHP4)

  • Verstehe ich dich richtig, das so in etwa dein momentaner
    Algorithmus aussieht:

    Code
    results = Liste
    for each hash in file:
        for each email in database:
            if sha1(email) == hash:
                 results.add(email)

    Folgende Ansaetze:

    1. Mach die innere Schleife direkt auf datenbankebene:
    "SELECT email FROM tablename WHERE sha1(email) = hash"
    => nur noch 19000 abfragen.

    2. Mach auch die aussere Schleife auf Datenbankebene:
    "SELECT email FROM tablename WHERE SHA1(email) in (hash1,hash2,hash3,...)
    => nur mehr 1 (etwas laengere) Abfrage.

    3. berechne die hashes von allen emails in einem preprocessing schritt und speichere diese hashes
    in einer Hilfstabelle oder einem Hilfsfeld in der Datenbank. Dann ist die Abfrage nurmehr:

    "SELECT email FROM tablename WHERE stored_hash in (hash1,hash2,hash3,...)"


    Ich vermute, dass dann die ganze Berechnung keine 5 sekunden dauert.

  • Ich würde versuchen das Problem zu teilen und es in "30sec-Pakete"(?) aufzusplitten.

    Wenn das Teilproblem gelöst würde ich soetwas senden (nicht getestet)

    PHP
    <script>window.location.href="foo?id=<?php echo ($i+1);>";</script>

    Somit hat man auch eine Art Fortschrittsanzeige.

  • Das mit dem wiederaufrufen des Scriptes war mir zu aufwendig - aber danke.


    Danke auch für den Tipp alles in SQL abfragen zu packen. Hat die Performance um ca. 20-30% erhöht und somit auch größere Listen möglich gemacht - bei sehr großen listen funkts noch immer nicht (script hört einfach nicht mehr auf) aber dieser task liegt nicht in meinem interesse.

    Folgend schaut der Code aus:

    (überschlagener code)
    Also zuerst wird das File genommen in 20 Byte blöcke geteilt und in eine temporäre tabelle geschrieben. Dann werden alle mails die überprüft werden sollen abgefragt und in der ergebnisschleife jeweils mit dem temp_table des importfiles vergleichen - wird was gefunden wird es in das bad_mails_found array geschrieben.

    Ich würde gerne alles in einer SQL abfrage machen, nur gibts da folgendes Problem:
    Normalerweise ergibt sha1() einen 40 stellige hex string - doch im file sind es sha1 der form 20 stellig im binary modus. PHP(5) hat dafür das extra argument sha1(string,RAW_BINARY MODE). In PHP 4 kann man das mit dem befehl pack("H*",sha1(string)) lösen. Nur weiß ich nicht wie ich das in der SQL abfrage mach da ich in SQL nur SHA1 kenn das einen 40 byte string erzeugt?

  • Ich weiß nicht warum das Script zu laufen aufhört, vielleicht kannst du es ja auch mal von der Kommandozeile aufrufen und das Problem so besser identifizieren.

    Außerdem könntest du schaun was passiert wenn du hie und da Text ausgibst und dann flush() aufrufst bzw. vorher überhaupt ob_implicit_flush(true) aufrufst.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!