Ankündigung

Einklappen
Keine Ankündigung bisher.

Wechsel von MyISAM auf InnoDB

Einklappen

Neue Werbung 2019

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

  • Wechsel von MyISAM auf InnoDB

    Hallo,
    ich überlege (aufgrund der Eigenschaft von InnoDB, zeilenweise zu locken anstatt ganze Tabellen wie MyISAM), meine sämtlichen DB-Tabellen auf InnoDB umzustellen.

    (korrigiert mich, wenn ich falsch liege und mir das ganze gar nix bringt)

    Muss ich in meinen Abfragen etwas umstellen (Syntax) ?
    Meine Abfragen laufen (meist) über PDO mit prepared Statements.
    Hier muss ich ja nur angeben, ob mysql oder anderes DB-System. Die Art der Tabelle ist hier eigentlich egal, sehe ich das richtig?

    Wenn ich das alles während des laufenden Betriebs einer Anwendung umstelle (also z.B. nachts um 1 Uhr, wenn so gut wie nix läuft) - kann mir dann was passieren? (Datenverlust? Nicht erreichbar?)

    Ich hab mich auch u.a. hier (http://web-union.de/382) etwas informiert.
    Mein Problem wären hier die Updates - die dauern meines Erachtens auch schon bei meiner MyISAM schon sehr lange.
    In welchem Verhältnis wäre das dann noch länger, z.B. bei ca. 3000 Datensätze?

    Der Befehl wäre:
    Code:
    alter table TABLE_NAME ENGINE=innodb;
    Wobei ich es wohl mit phpMyAdmin erledigen werde.

    Was spricht dagegen, was dafür?

  • #2
    Nein, die Queries bleiben gleich. Und nein, das ist btw. nicht der einzige Befehl, den du ausführen solltest. Wenn du schon auf InnoDB umsteigst empfehle ich gleich alle Fremdschlüssel zu erstellen.

    Ja, PDO ist es egal, welche Tabellenart da dran hängt.

    Ja, da kann verdammt viel schief gehen. Das wirst du schon merken. Mach es Freitags nacht - dann hast du 2 Tage zum Korrigieren.

    3'000 Zeilen Updaten (einmal pro Minute?) für ein RDBMS noch etwas, was es vor dem Warmlaufen erledigt.

    Achte auf ein Backup (mysqldump), versuche das Ganze zuerst in einer Development-Umgebung (virtuelle Maschine wenn's sein muss). Spiel es einige Male durch und und und...
    [URL="https://github.com/chrisandchris"]GitHub.com - ChrisAndChris[/URL] - [URL="https://github.com/chrisandchris/symfony-rowmapper"]RowMapper und QueryBuilder für MySQL-Datenbanken[/URL]

    Kommentar


    • #3
      Zieh' dir bei nächster Gelegenheit mal ein Tutorial bezüglich "Deadlocks" rein. Das "zeilenweise" Sperren von Datensätzen weicht in der Realität teils weit vom Klang der Worte ab

      Kommentar


      • #4
        Ja. Super. Danke für die Antworten und Anregungen.

        Nur kurz:
        @ChristianK: was mach ich dann da großartig falsch bei meinen Updates? Ich lasse aus einer Tabelle mit derzeit nur 2.500 Einträgen eine CSV erstellen und nach dem Erstellen diese via Update-Statement als "exportiert" markieren.
        Die Datei wird dann direkt mit den richtigen Headern zum Browser geschickt.
        Dauert teilweise 20-30 sek. Kommt mir halt sehr lang vor.
        Wenn die mal größer werden, dauert das ja gut und gern mal über eine Minute...
        Da fehlt mir halt die Erfahrung.

        Und wg. Freitag nacht - geht genauso wenig wie unter der Woche, weil 24/7 da Betrieb herrscht. Leider.

        Kommentar


        • #5
          Das ist schwierig zu sagen - eine tiefergehende Analyse ist da eventuell durchaus nötig (melde dich bei Bedarf per PN).

          Für eine solche Anzahl an Einträge sollte das jedoch durchaus schneller gehen. Wenn du Prepared Statements verwendest und mehrere Inserts auf einmal sendest, dann sollte das durchaus schneller gehen.

          Eine Live-Migration geht im Besten Falle auch nicht so lange. Du musst sie nur genug lange üben .
          [URL="https://github.com/chrisandchris"]GitHub.com - ChrisAndChris[/URL] - [URL="https://github.com/chrisandchris/symfony-rowmapper"]RowMapper und QueryBuilder für MySQL-Datenbanken[/URL]

          Kommentar


          • #6
            Bei der Symptombeschreibung vermute ich mal Queries in Schleifen...
            Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

            Kommentar


            • #7
              Ja. Queries in Schleifen.
              Net gut? Dumme Frage aber wie macht man das sonst wenn ich durch best. Datensätze eine bestimmte Spalte ändern will?
              Also die erste Query gibt mir alle Datensätze, die ich für die CSV brauche.
              Dann wird das Query-Ergebnis Zeile für Zeile durchgegangen und eine CSV erstellt und in dieser Schleife wird für jeden Datensatz davon ein UPDATE auf eine best. Spalte dieses Datensatzes gemacht.
              Verbesserungsvorschläge?

              Kommentar


              • #8
                Zitat von dawson77 Beitrag anzeigen
                Ja. Queries in Schleifen.
                Net gut?
                Nein. Skaliert nicht und ist fas immer komplett sinnfrei.

                Verbesserungsvorschläge?
                Müßte man im Detail sehen.
                PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

                Kommentar


                • #9
                  Also die erste Query gibt mir alle Datensätze, die ich für die CSV brauche.
                  Das ist gut.

                  Dann wird das Query-Ergebnis Zeile für Zeile durchgegangen und eine CSV erstellt und in dieser Schleife wird für jeden Datensatz davon ein UPDATE auf eine best. Spalte dieses Datensatzes gemacht.
                  Das ist schlecht.
                  Aber, ehrlich gesagt, manchmal unvermeidlich.
                  Kommt drauf an, mit welchen Werten aktualisiert wird. Wenn es immer unterschiedliche Werte sind, kann man das tatsächlich nur einzeln machen. Aber wie akretschmer schon sagte: Müsste man im Detail sehen.
                  Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

                  Kommentar


                  • #10
                    Wtf? Doppelpost entfernt
                    Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

                    Kommentar


                    • #11
                      im Detail: (etwas gekürzt...)

                      Code:
                      if ($export=="1") {
                      	
                        // Dateiname festlegen
                        $dateiname = "soundso.csv";
                        $tabelle = "tabellenname";
                      		
                        // PDO SQL-Abfrage erstellen
                        $sql = "SELECT * FROM ".$tabelle." WHERE export<='' OR export='0'";
                        $stmt = $dbh->prepare($sql);
                        $stmt->execute();
                      			
                        $daten = "";
                      	
                        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
                      			
                          // Ausgabe-Zeile erstellen
                          $zeile = $row['eins'].";".$row['zwei'].";".$row['drei'].";".$row['vier']."\r\n";
                          // Ausgabe-Zeile formatieren in ANSI
                          $zeile = iconv("UTF-8", "WINDOWS-1252", $zeile);
                          $daten .= $zeile;
                      
                          // folgende Zeile setzt FLAG_EXPORT auf "Name", wenn vorher ANGEKREUZT wurde
                          //$_POST['flag_export'] = "1";
                          if (isset($_POST['flag_export']) AND $_POST['flag_export']>"") {
                            if (updateExport($dbh, $feld, $name, $row['eins'])) {
                              // alles OK
                            }
                          }
                        }
                      }
                      	
                      if (!erstelleCSV($dateiname, $daten)) {
                        echo erstelleCSV($pfad, $daten);
                      }
                      
                      header('Content-Type: text/x-csv');
                      header('Expires: ' . gmdate('D, d M Y H:i:s') . ' GMT');
                      header('Content-Disposition: attachment; filename='.$dateiname.'.csv');
                      header('Pragma: no-cache');
                      
                      echo $daten;
                      Code:
                      function updateExport($dbh, $feld, $name, $id) {
                        $tabelle = "tabellenname";
                        $sql = "UPDATE ".$tabelle." SET ".$feld."= :name WHERE id= :id";
                        $stmt = $dbh->prepare($sql);
                        $stmt->execute(array(':name' => $name, ':id' => $id));
                      		
                        return $stmt->rowCount() ? true : false;
                      }

                      Kommentar


                      • #12
                        Ahhh, du setzt nur das "exported" flag auf 1?

                        DAS kann man in einem Rutsch erledigen!
                        Sammele dazu die ID's der Datensätze, die du ausgelesen hast und feuere am Ende nur 1 einziges Query (UPDATE... WHERE ID IN(...))
                        Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

                        Kommentar


                        • #13
                          Ahjetztja....
                          Dann mach ich mir ein $array mit allen IDs und am Ende eine solche Query:
                          Code:
                          "UPDATE `tabelle` SET `feld` WHERE `id` IN (" . implode(',', $array) . ")";
                          Richtig?

                          @Istegelitz: ich find deinen Brotspruch einfach nur goil. Genauso isses.

                          Kommentar


                          • #14
                            Exakt. Anstatt hunderte von UPDATE Queries feuerst du nur noch 1, das sollte einen spürbaren Performancegewinn ergeben.
                            Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

                            Kommentar


                            • #15
                              Ähm, anstelle das Array zu imploden und einen riesen Query an die Datenbank zu senden, könntest du das in auch mit einem SELECT erstellen. Dann bleibt alles DB-seitig.
                              [URL="https://github.com/chrisandchris"]GitHub.com - ChrisAndChris[/URL] - [URL="https://github.com/chrisandchris/symfony-rowmapper"]RowMapper und QueryBuilder für MySQL-Datenbanken[/URL]

                              Kommentar

                              Lädt...
                              X