250 000 Update-Statements

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

  • 250 000 Update-Statements

    Hi,
    vielleicht hat ja von euch jemand einen Tipp..
    ich muss 250000 Update-Statements absetzen auf eine Tabelle.
    Im Prinzip ganz simpel:
    Update tabelle set jahr = 2001 where id = xy

    id ist primärschlüssel, die spalte "jahr" integer.

    Egal ob ich das per Console als Script lade oder über php versuche, jedesmal brauche ich schon zwei, drei Minuten nur für 100 Statements.

    hat jemand eine Idee, wie ich das beschleunigen kann?

    Gruß + danke
    hal

  • #2
    Wieso musst du das für jeden Datensatz einzeln machen?

    UDPATE tabelle SET jahr = 2001
    ich glaube

    Kommentar


    • #3
      Hallo,

      also ich kann dir warscheinlich hier nicht viel helfen weil ich mit dieser Problematik zum Glück noch nicht zu kämpfen hatte.

      Aber die Frage wäre, ob es da möglich ist, dass du den gesamten String in einem überträgst und ausführen lässt (z.B. getrennt durch ';') oder ob es überhaupt nötig ist soviele Updates abzusetzen.

      Ist das jetzt eine einmalige Aktion? Weil ich kann mir kaum vorstellen, dass 250000 Jahreszahlen regelmäßig in komplett andere Werte geändert werden.

      Wenn die Werte auch nur irgendwie berechenbar sind, empfiehlt es sich natürlich, den SQL-Server das berechnen zu lassen:

      update tbl set jahr = jahr + 1 ....

      oder so ähnlich eben.

      Kommentar


      • #4
        Ich gehe jetzt mal davon aus, dass du zu jedem Eintrag eine individuelle Zahl speichern willst, sonst hättest du dieses Vorhaben sicher nicht.

        Egal ob ich das per Console als Script lade oder über php versuche, jedesmal brauche ich schon zwei, drei Minuten nur für 100 Statements.
        Das ist pervers! Eine so simple Query sollte nie im leben ein bis zwei Sekunden dauern. Auch nicht, wenn 100 Stück hintereinander folgen.

        (Ich kenn genug hier im Forum, die Ihre Applikationen nach diesem Schema programmieren. )

        Kommentar


        • #5
          Ganz sicher, dass die ID als Primärschlüssel indiziert ist? Kann ich mir ehrlichgesagt kaum vorstellen bei der Rechenleistung.
          Nur wenige wissen, wieviel man wissen muss, um zu wissen, wie wenig man weiß.

          Kommentar


          • #6
            Hier ist die Tabellen-Definition:

            CREATE TABLE `abc`.`tabellei` (
            `appln_id` int(11) NOT NULL default '0',
            `person_id` int(11) NOT NULL default '0',
            ...
            `jahr` int(10) unsigned NOT NULL,
            PRIMARY KEY USING BTREE (`person_id`,`appln_id`),
            KEY `ind_country` (`inv_cou`),
            KEY `ind_vorname` (`inv_vorname`)
            ) ENGINE=MyISAM DEFAULT CHARSET=utf8;

            Da soll natürlich jeder Datensatz einen speziellen Wert bekommen, deshalb muss das für jeden Datensatz einzeln gemacht werden, das wurde in meinem ersten Posting vielleicht nicht deutlich genug...
            Der Wert lässt sich auch nicht berechnen, sondern hängt mit der appln_id zusammen. Allerdings ist es eine einmalige Aktion.
            Vielleicht ist auch noch wichtig, dass so ein Update mehrere Datensätze betreffen kann (weil die appln_id als Bestandteil des kombinierten Schlüssels mehrfach vorkommen kann.) Deshalb kann ich es auch nicht mit einem insert / Flat-File machen - zumindest hatte ich noch keine zündende Idee, wie ich das hinbekommen könnte ohne dass die anderen Daten futsch gehen.

            Mir ist das auch unerklärlich, warum das so ewig dauert.

            Ich sollte noch dazu sagen, ingesamt umfasst die Tabelle 560.000 Datensätze.

            Gruß
            hal
            Zuletzt geändert von hal45; 22.06.2007, 21:38.

            Kommentar


            • #7
              Ahja... da isses ja schonwieder bissel was anderes als am Anfang. Benutzt du denn beim Update stets person_id und appln_id? Wenn nicht würde ich da mal drüber nachdenken.
              Nur wenige wissen, wieviel man wissen muss, um zu wissen, wie wenig man weiß.

              Kommentar


              • #8
                EXPLAIN SELECT jahr FROM tabelle WHERE id = x;
                ANALYZE tabelle;
                OPTIMIZE tabelle;
                LOCK TABLES tabelle WRITE; ... UNLOCK TABLES;
                START TRANSACTION; ... COMMIT;

                Alles schon versucht?

                Kommentar


                • #9
                  Hi,
                  also erstmal danke für eure Anregungen..
                  ich habs jetzt aber ganz anders gelöst. hab ne neue Tabelle gemacht und mir die werte mit select aus der anderen Tab jahreweise geholt und dann mit Insert into...select... jahreweise wieder eingefügt und da ging es ratzfatz (waren nur 5 verschiedene Jahre)...

                  @ArSeN: das versteh ich nicht ganz, wie du das meinst? Ich hab eim update nur auf appln_id zugegriffen, weil mir die person_id nicht bekannt ist und die ja auch unterschiedlich sein kann für ein update.. Meinst du, dass es deshalb solange gedauert hat, weil ich den key nur "halb" angegeben konnte und die andere Hälfte variabel war und somit mehrere Datensätze betroffen hat?

                  @onemorenerd:
                  alles hatte ich nicht ausprobiert, aber das eine oder andere ;-)

                  aber nu hab ich s ja und kann nun endlich ins Wochenende gehen.
                  Gruß + Dank
                  hal

                  Kommentar


                  • #10
                    Original geschrieben von hal45
                    @ArSeN: das versteh ich nicht ganz, wie du das meinst? Ich hab eim update nur auf appln_id zugegriffen, weil mir die person_id nicht bekannt ist und die ja auch unterschiedlich sein kann für ein update.. Meinst du, dass es deshalb solange gedauert hat, weil ich den key nur "halb" angegeben konnte und die andere Hälfte variabel war und somit mehrere Datensätze betroffen hat?
                    Nicht nur das, apple_id ist der hintere Teil vom index, demnach wird der index mit %<id> durchwühlt, was langsamer ist als <id>%, da die Struktur halt ein bin-Baum ist
                    Den Rest hab ich mir jetzt nicht angeschaut, ka ob es wirklich deshalb so langsam war~

                    Ein netter Guide zum übersichtlichen Schreiben von PHP/MySQL-Code!

                    bei Klammersetzung bevorzuge ich jedoch die JavaCoding-Standards
                    Wie man Fragen richtig stellt

                    Kommentar


                    • #11
                      Mann kann das ganze auch in einer query machen... hab jetzt nicht jeden Beitrag gelesen, is ja schon spät

                      PHP-Code:
                      UPDATE tab SET jahr 2001 WHERE id IN(1,2,4,5,6,...) 
                      Evtl, wenn mann viele ID's hat, muss man die MAX_QUERY_LENGTH per SET heraufsetzen. Für nen mom geht das aber....

                      Nichtsdestotrotz halte ich es aber auch mit Tobiaz, das bei einer "vernünftigen" Tabellen Struktur das ganze kein Problem sein sollte...

                      Kommentar


                      • #12
                        ghostgambler hats eigentlich schon gesagt: Ich meine damit, dass der ganze Index (Primärschlüssel) ein Binärbaum ist, und es daher auch nur wirklich sinnvoll ist, wenn du den kompletten Primärschlüssel im WHERE-Statement angibst. Dann sollte es wirklich um einiges schneller gehen.
                        Nur wenige wissen, wieviel man wissen muss, um zu wissen, wie wenig man weiß.

                        Kommentar


                        • #13
                          danke nochmal für eure Antworten...
                          das Problem war ja nur, dass mir eben nicht der gesamte Primärschlüssel bekannt war, sondern nur der eine Wert, deshalb konnte ich ihn auch nicht komplett angeben.

                          Und auch die Variante mit IN (...) ist bei 200.000 ids, die dann da hätten aufgelistet werden müssen, sicher auch nicht schneller - sofern man das überhaupt hingekriegt hätte.

                          Natürlich könnte man jetzt zu Recht argumentieren, wenn das Feld nur in Abhängigkeit zu einem Teil des Primärschlüssels steht, die Tabelle nicht mehr den Normalisierungsregeln entspricht, aber in dem Fall ging es nicht anders.

                          Gruß
                          hal

                          Kommentar

                          Lädt...
                          X