norman: sortieren von großen datenmengen (plus perl)

hallo forum!

ich bin mit meinem mysql-latain am ende. wie kann man möchlichst ressourcensparend große datenmengen sortieren?

ich habe ne grooooße db und will nach "id" (index) sortieren ("id" ist nicht unique). scheinbar lädt sich mysql die ganze db zunächst in den speicher und sortiert erst dann oder so... jedenfalls ist eine 1.3 GB große auslagerungsdatei von windows das ergebnis.

hat jemand eine idee wie ich mit mysql ressourcensparend sortieren kann.

(select * from db order by id desc)

viele grüße
norman

  1. Sup!

    Also, wenn man die Liste unsortiert speichert, kostet das Sortieren natürlich eine Menge Zeit.
    Wenn man die Liste schon sortiert speichern kann (gute DBs können das), dann kostet Einfügen oder Löschen Zeit.

    Da muss man Abwägen, welcher Fall öfter vorkommt - Lesen oder Schreiben. In Deinem Fall wäre wahrscheinlich das schon sortierte Speichern von Vorteil, man muss doch einen Index auch über nicht-unique Daten legen können, dann sollten die Daten schon quasi vorsortiert gespeichert werden.

    Gruesse,

    Bio

    --
    Elite ist mein zweiter Vorname
    1. Hi,

      Also, wenn man die Liste unsortiert speichert, kostet das Sortieren natürlich eine Menge Zeit.

      wird's nicht immer unsortiert gespeichert?

      Wenn man die Liste schon sortiert speichern kann (gute DBs können das), dann kostet Einfügen oder Löschen Zeit.

      Ganz schoen viel Zeit.

      Da muss man Abwägen, welcher Fall öfter vorkommt

      Nein. Man muss unsortiert speichern.

      • Lesen oder Schreiben. In Deinem Fall wäre wahrscheinlich das schon sortierte Speichern von Vorteil,

      Du meditierst vemutlich ueber den Fuellfaktor von Indizes?

      man muss doch einen Index auch über nicht-unique Daten legen können, dann sollten die Daten schon quasi vorsortiert gespeichert werden.

      Also, der Mann klagt ueber die schlechte Performance von Sortierungen unter 'MySQL'. Da koennte man ihn darauf hinweisen, dass intelligent gesetzte Indizes das Sortieren deutlichst performanter machen koennen. Mehr faellt mir dazu auch nicht ein.

      Gruss,
      Lude

      1. hmmm, index performanter:

        z.z. sieht der index so aus: we23sdds_dfd1212gff12 (mit VARCHAR(255))

        mit CHAR(50) könnte das ding schneler werden?!

        oder was sagt ihr dazu?

        gruß
        norman

        1. Hi,

          z.z. sieht der index so aus: we23sdds_dfd1212gff12 (mit VARCHAR(255))

          in meiner Welt ('MS SQL Server') sieht ein Index z.B. so aus:
          'CREATE  INDEX [REINRAUS_REINRAUS_7B1] ON [dbo].REINRAUS_REINRAUS_7B WITH  FILLFACTOR = 100 ON [PRIMARY]' (was immer das auch heissen mag ;-)

          Die Indizes sind Zeigermengen, die in (relativ) kleinen Dateien (oder vergelichbaren Strukturen) gehalten werden.

          mit CHAR(50) könnte das ding schneler werden?!

          Was meinst Du denn damit?

          Ist es eine Idee, dass Du erst Untermengen bildest und dann anfaengst zu sortieren. Nach meiner Kenntnis macht es fast nie Sinn die gesamte Datensatzmenge sortiert auszugeben, wenn die Datensatzmenge so gross ist, wie von Dir angegeben.

          Gruss,
          Lude

          1. wenn ichs richtig verstanden habe ...dann kopiere ich die spalte "meine_id" (das ist der index nach dem sortiert werden soll) aus der "großen" tabelle in die tabelle "id_sort" und sortiere nur diese kleine tabelle. später wird dann über die "id_sort" - tabelle die große tabelle seleceted

            z.b.:

            select * from grosse_db, id_sort where grosse_db.meine_id = id_sort.meine_id;

            gruß
            norman

            1. Hi,

              wenn ichs richtig verstanden habe ...

              da ich Dich jetzt nicht verstanden habe, ist die Wahrscheinlichkeit hoch, dass Du mich nicht verstanden hast.

              Aber mal ganz praktisch:
              Was willst Du erreichen? - Eine sortierte Teilliste oder eine sortierte Komplettliste?

              'select * from db order by id desc' koennte z.B. durch
              'select * from (select * from db where krit = 'krit') Dummy order by Dummy.id desc' ersetzt werden.

              Oder auch durch 'select * from db where krit = 'krit' order by id desc'

              Gruss,
              Lude

              1. ich brauche leider eine komplette sortierte liste...

                gruß,
                norman

                1. ich brauche leider eine komplette sortierte liste...

                  Naja, wenn deine Datenmenge so gross ist und du diese komplett im Speicher halten musst, dann ist es doch ganz normal, dass eine so große Auslagerungsdatei entsteht, oder? wo sollen die Daten denn hin, wenn der Speicher nicht mehr ausreicht?

                  Dass hat aber weder was mit einem Index noch mit dem sortieren zu tun (ich hoffe mal du läßt mySQL sortieren und das sortierfeld ist indiziert?).

                  Struppi.

                  1. hi struppi,

                    ja, das sortier-feld ist indiziert. liegt die schlechte performance vielleicht an meinem perl-script? :

                    my $sth = $dbh->prepare("SELECT SQL_BIG_RESULT * FROM log\_session ORDER BY session\_id");
                    $sth->execute();

                    while (my @line = $sth->fetchrow()) {

                    tun was!

                    }

                    gruß,
                    norman

                    1. hi struppi,

                      ja, das sortier-feld ist indiziert. liegt die schlechte performance vielleicht an meinem perl-script? :

                      keine Ahnung

                      my $sth = $dbh->prepare("SELECT SQL_BIG_RESULT * FROM log\_session ORDER BY session\_id");
                      $sth->execute();

                      while (my @line = $sth->fetchrow()) {

                      bis hierhin ist ja alles völlig ok

                      tun was!

                      aber je nachdem was "tun was" bedeutet kann hier natürlich dien Problem liegen.
                      Du liest hier alle Datensätz mit allen Feldern ein?
                      Und die DB ist gross?

                      Wie gesagt, dann darfst du dich nicht wundern über performance Probleme. mySQL ist soweit ich das mitbekommen schon in der Lage mit Datenbanken selbst im Gigabyte Bereich umzugehen.

                      Struppi.

                      1. while (my @line = $sth->fetchrow()) {
                        my $string = join ("\t",@line);

                        #string-operationen: etwa 5000 zeilen bearbeiten und in eine andere #db-tabelle schreiben, dann wieder einlesen...
                        }

                        in der while-schleife passiert soweit nichts aufregendes nur ein paar string-operationen deren perfomance eigentlich ok sein müsste.

                        wird eigentlich die "select * from db" - abfrage am anfang komplett in den speicher geschrieben? das würde die große auslagerungsdatei erklären.

                        norman

                        aber je nachdem was "tun was" bedeutet kann hier natürlich dien Problem liegen.
                        Du liest hier alle Datensätz mit allen Feldern ein?
                        Und die DB ist gross?

                        Wie gesagt, dann darfst du dich nicht wundern über performance Probleme. mySQL ist soweit ich das mitbekommen schon in der Lage mit Datenbanken selbst im Gigabyte Bereich umzugehen.

                        Struppi.

      2. Sup!

        Hi,

        Also, wenn man die Liste unsortiert speichert, kostet das Sortieren natürlich eine Menge Zeit.

        wird's nicht immer unsortiert gespeichert?

        Nun, jedes bessere Datenbanksystem versucht zumindest, die s.g. topologische Struktur der Daten zumindest für einen als besonders wichtig gekennzeichneten Index zu erhalten, damit die Daten eine möglichst hohe Lokalität haben und Speicherzugriffe gespart werden.

        Wenn man die Liste schon sortiert speichern kann (gute DBs können das), dann kostet Einfügen oder Löschen Zeit.

        Ganz schoen viel Zeit.

        Naja, es geht, solange das Einfügen oder Löschen ein bestimmtes Maß nicht übersteigt, recht schnell.

        Da muss man Abwägen, welcher Fall öfter vorkommt

        Nein. Man muss unsortiert speichern.

        Man kann die Daten in Segmente, Seiten und Blöcke aufteilen... aber ich halte hier keine Datenbankvorlesung.

        • Lesen oder Schreiben. In Deinem Fall wäre wahrscheinlich das schon sortierte Speichern von Vorteil,

        Du meditierst vemutlich ueber den Fuellfaktor von Indizes?

        Ein guter Index sollte erweiterbar sein, wer mit statischem Hashing arbeitet, ist selbst schuld...

        Also, der Mann klagt ueber die schlechte Performance von Sortierungen unter 'MySQL'. Da koennte man ihn darauf hinweisen, dass intelligent gesetzte Indizes das Sortieren deutlichst performanter machen koennen. Mehr faellt mir dazu auch nicht ein.

        Intelligente Datenbankadministration könnte auch helfen, sofern mysql z.B. das Festlegen einer primären Sortierreihenfolge unterstützt.

        Wenn man nur mehrere Indizes anlegt, dann erkennt mysql vielleicht nicht, welcher Index besonders wichtig ist, und das Sortieren nach Index XY erfordert dann trotz allem das Einlesen aller Daten ins RAM.

        Gruesse,

        Bio

        --
        Elite ist mein zweiter Vorname
        1. Hi,

          Da muss man Abwägen, welcher Fall öfter vorkommt

          Nein. Man muss unsortiert speichern.

          Man kann die Daten in Segmente, Seiten und Blöcke aufteilen... aber ich halte hier keine Datenbankvorlesung.

          Du bist durchaus eingeladen etwas zur Segmentierung der Daten, also der "Blockbildung", hier beizutragen.

          Wenn man nur mehrere Indizes anlegt, dann erkennt mysql vielleicht nicht, welcher Index besonders wichtig ist, und das Sortieren nach Index XY erfordert dann trotz allem das Einlesen aller Daten ins RAM.

          Das waere allerdings eine Todsuende von 'mySQL'.   ;-)

          Gruss,
          Lude