Nina2: Mysql: VARCHAR

Hallo,

gerade muss ich mich mit einer Tabelle herumärgern, deren Design gerade umgestellt wird.
Sie umfasst etwa 3 Mio Datensätze (insgesamt 150MB), sodass es sehr auffällt, wie langsam die Update Queries bearbeitet werden, obwohl auf c5id ( INT (7) ) im WHERE clause ein Index gesetzt wurde.
Nun frage ich Euch an dieser Stelle, ob das denn sein kann, dass die Ausführung jedes der Update Queries ca 15 sec dauert oder ob bei dem Index irgendwas schief gelaufen ist? :(
Oder ob es alternativ dazu eine Möglichkeit, das abseits vom Script mit einem schönen Mysql Query lösen lässt?
Es wird von jedem Datensatz (ID=c5id) das VARCHAR(6) Feld namens cs ausgelesen: Davon die ersten beiden Chars bezeichnen das erste Feld, das auf 1 gesetzt werden soll; die nächsten 2 das 2. Feld und die nächsten 2 das 3.Feld. Dann soll es gesetzt werden und mit der nächsten Zeile weitergehen...

$query='SELECT c5id,cs FROM data5;';
$res=mysql_query($query);
for($i=0;$i<mysql_num_rows($res);$i++)
{
 $c5id=mysql_result($res,$i,'c5id');
 $cs=mysql_result($res,$i,'cs');
 $query="UPDATE data5 SET ".$cs[0].$cs[1]."=1,".$cs[2].$cs[3]."=1,".$cs[4].$cs[5]."=1,".$cs[6].$cs[7]."=1,".$cs[8].$cs[9]."=1 WHERE (c5id='$c5id') LIMIT 1;";
...
}

Danke für Tipps

  1. Hallo,

    gerade muss ich mich mit einer Tabelle herumärgern, deren Design gerade umgestellt wird.

    was wohl schon lange überfällig ist. Das Design sieht mal selten dämlich aus.

    Sie umfasst etwa 3 Mio Datensätze (insgesamt 150MB), sodass es sehr auffällt, wie langsam die Update Queries bearbeitet werden, obwohl auf c5id ( INT (7) ) im WHERE clause ein Index gesetzt wurde.

    Langsam. Mich kommt das verdammt schnell vor.

    $query='SELECT c5id,cs FROM data5;';

    Ist c5id eindeutig?

    $res=mysql_query($query);
    for($i=0;$i<mysql_num_rows($res);$i++)

    Sind das dann 3 Millionen einzelne Updateanweisungen. Wow!
    Wieviele Spalten können da vorkommen?

    {
    $c5id=mysql_result($res,$i,'c5id');
    $cs=mysql_result($res,$i,'cs');
    $query="UPDATE data5 SET ".$cs[0].$cs[1]."=1,".$cs[2].$cs[3]."=1,".$cs[4].$cs[5]."=1,".$cs[6].$cs[7]."=1,".$cs[8].$cs[9]."=1 WHERE (c5id='$c5id') LIMIT 1;";

    Laut Deinen Angaben ist cs VARCHAR(6), dafür wird munter auf das siebte bis zehnte Zeichen zugegriffen. Nett. Gibt das keine Fehlermeldung?

    Wieviele dieser Spalten gibt es nun und wieviele Zeichen kann cs enthalten?
    Tipp: Die Designänderung sollte schnellstmöglich erfolgen und vernünftig ausfallen.

    Vinzenz

    1. Hello,

      ich möchte auch an dieser Stelle nochmals an die unterschiedlichen Einstellungen für verschiedene Datenbankgrößen (Speicherbedarf) erinnern und würde mich freuen, wenn es denn mal eine Rückmeldung gäbe, ob das bei MySQL 5.x auch immer noch so gravierende Unterschiede macht...

      Ich finde den Thread jetzt nicht wieder.

      Aber die alten Möglichkeiten verlinke ich nochmals:
      http://selfhtml.bitworks.de/mysql/config-samples/

      Bitte aber schauen, ob es inzwischen neuere Tipps von MySQL gibt.

      Ein harzliches Glückauf

      Tom vom Berg

      --
      Nur selber lernen macht schlau
      http://bergpost.annerschbarrich.de
      1. Danke,
        werde das mal überprüfen.
        Komme jedoch gerade nicht dazu nachdem es wohl länger dauern wird, sich da einzuarbeiten.

    2. Hi,

      for($i=0;$i<mysql_num_rows($res);$i++)

      Sind das dann 3 Millionen einzelne Updateanweisungen. Wow!

      Vielleicht gewinnt man ein bisschen was, wenn man nicht so viele Update-Queries einzeln von PHP aus abfeuert -

      $query="UPDATE data5 SET ".$cs[0].$cs[1]."=1,".$cs[2].$cs[3]."=1,".$cs[4].$cs[5]."=1,".$cs[6].$cs[7]."=1,".$cs[8].$cs[9]."=1 WHERE (c5id='$c5id') LIMIT 1;";

      • sondern das hier lieber direkt MySQL-seitig mit dessen Stringfunktionen macht?

      Wird bei 3 Mio. Datensaetzen vermutlich immer noch ziemlich lange dauern, und ggf. sogar abbrechen.

      Dem koennte man entgegenwirken, in dem man das ganze intervalweise macht; oder aber, in dem man Abbrueche in Kauf nimmt, und sich beim Updaten in einer zusaetzlichen (temporaeren) Spalte ein Flag setzt, dass der Datensatz bereits bearbeitet wurde - und das Update jagt man dann nur ueber die Datensaetze, bei denen das Flag noch nicht gesetzt ist - so lange, bis man alle durch hat. (Ginge so natuerlich nur, wenn es nach einem abgebrochenen Update kein Rollback gibt.)

      MfG ChrisB

    3. Hi,

      Sie umfasst etwa 3 Mio Datensätze (insgesamt 150MB), sodass es sehr auffällt, wie langsam die Update Queries bearbeitet werden, obwohl auf c5id ( INT (7) ) im WHERE clause ein Index gesetzt wurde.

      Langsam. Mich kommt das verdammt schnell vor.

      Der Update Query (v.a. mit Limit 1) hat genau einen Datensatz zu ändern und nachdem c5id Primary Key, Auto increment und natürlich eindeutig ist, sollte die Zeile sehr schnell gefunden werden können. Und genau das wundert mich eben bzw. warum das nicht schneller geht..?

      Ist c5id eindeutig?

      ja

      Sind das dann 3 Millionen einzelne Updateanweisungen. Wow!

      jeder einzelne UPDATE Query dauert 15 sec! werde es so nicht durchlaufen lassen...

      Wieviele Spalten können da vorkommen?

      Das einlesen geht ruck zuck. Nur eben das Updaten nicht :/

      Laut Deinen Angaben ist cs VARCHAR(6), dafür wird munter auf das siebte bis zehnte Zeichen zugegriffen. Nett. Gibt das keine Fehlermeldung?

      Mein Fehler. Es ist VARCHAR(10)

      1. Hello,

        jeder einzelne UPDATE Query dauert 15 sec! werde es so nicht durchlaufen lassen...

        Genau das ist eben ein Indiz dafür, dass das gewählte Speichermodell nicht zur Größe und Ausgestaltung der DB passt. Einen Index zu erneuern erfordert vom DBMS extrem viel Kraft, wenn der nicht (weinigstens "seitenweise") in den Speicher passt.

        Ein harzliches Glückauf

        Tom vom Berg

        --
        Nur selber lernen macht schlau
        http://bergpost.annerschbarrich.de
      2. Hallo

        Sie umfasst etwa 3 Mio Datensätze (insgesamt 150MB), sodass es sehr auffällt, wie langsam die Update Queries bearbeitet werden, obwohl auf c5id ( INT (7) ) im WHERE clause ein Index gesetzt wurde.

        Der Update Query (v.a. mit Limit 1) hat genau einen Datensatz zu ändern und nachdem c5id Primary Key, Auto increment und natürlich eindeutig ist,

        Dann ist die LIMIT-Klausel überflüssig. Weg damit, ab in die Tonne.
        Was sagt EXPLAIN zu einer Beispielquery? Was sagt die Speichernutzung durch MySQL (top), Toms Hinweis ebenfalls in Betracht ziehen.

        Wieviele dieser seltsamen Spalten gibt es? Das interessiert mich. Gibt es weitere Indexe, die durch das Update aktualisiert werden müssen?

        Freundliche Grüße

        Vinzenz