[MySQL] 1,4 Mio Datensätze, 2 Tables, First in - First out, hohe Last

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

  • [MySQL] 1,4 Mio Datensätze, 2 Tables, First in - First out, hohe Last

    Servus!

    Da ich irgendwie nicht mehr wirklich weiter weiß bzw. mir keine schöne Lösung einfällt, frag ich nun mal hier.


    Also ich hab 2 Tabellen:

    - gb_cache : 345.000 Datensätze [62 MB]
    - gb : 1,08 Mio. Datensätze [190 MB]

    Beide Tabellen identisch, d.h. selben Index, selbe Spalten etc.


    In jeder Tabelle stehen Gästebucheinträge von Community-Usern, d.h. in

    - gb_cache : max. 60 Einträge pro Benutzer
    - gb: der Rest, aber max. 340 (wird jede Nacht aufgeräumt)


    Bei jeden Eintrag in gb_cache wird überprüft ob mehr als 60 Einträge drin sind, wenn ja dann nach gb verschoben und in gb_cache gelöscht (First in – First out). Und genau hier vermute ich das Problem.

    Greifen 250 User gleichzeitig zu kein Problem. Aber werden es dann 300 und mehr fängt die Kiste an zu swappen = alles wird langsam. Meine Vermutung für das RAM zu müllen ist das updaten der Indexe der Tabellen.


    -> Also meine Variante ist nicht grade performant und mir fehlt einfach die Idee das ganze anders umzusetzen.

    Irgendwelche Vorschläge, Anregungen und Ideen? Mir fällt wie gesagt nichts Gescheites ein.



    Noch was zum Server:
    - Opteron 146 - 2 GHz
    - 1 GB RAM

    Zwar auch nicht grade der schnellste, aber ich denke der sollte normal die 300-350 Zugriffe ohne Probleme schaffen. Wäre da nicht das oben beschrieben Problem.


    Gruß haddi

  • #2
    Re: [MySQL] 1,4 Mio Datensätze, 2 Tables, First in - First out, hohe Last

    * Die Verschiebung per Cronjob realisieren

    * Die vielen Datensätze auf mehrere Tabellen aufteilen
    gb_0, gb_1, gb_2, gb_3, gb_4, gb_5, gb_6, gb_7, gb_8, gb_9
    und um an die Datensätze eines Users zu kommen wird dann user_idMOD10 gerechnet (in der aktuellen mysql-Version gibt es auch ein entsprechendes Feature, Partitioning genannt, ist halt nur noch eine Beta-Version...), verkleinert die Daten pro Tabelle

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

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

    Kommentar


    • #3
      Re: Re: [MySQL] 1,4 Mio Datensätze, 2 Tables, First in - First out, hohe Last

      Original geschrieben von ghostgambler
      * Die Verschiebung per Cronjob realisieren

      * Die vielen Datensätze auf mehrere Tabellen aufteilen
      gb_0, gb_1, gb_2, gb_3, gb_4, gb_5, gb_6, gb_7, gb_8, gb_9
      und um an die Datensätze eines Users zu kommen wird dann user_idMOD10 gerechnet (in der aktuellen mysql-Version gibt es auch ein entsprechendes Feature, Partitioning genannt, ist halt nur noch eine Beta-Version...), verkleinert die Daten pro Tabelle
      Verschiebung per Cronjob: Joa dann hätte ich aber Tags über die Cachetable voll, dann aus der Cache Table z.B.50 Einträge, das wären 3 Seiten bei 20 Beiträgen pro Seite; Dann könnt ich ab Seite 4 wieder aus der archiv table holen, unschöne sache. Die restlichen beiträge auf seite 3 aus der archivtable holen, auch doof für die weitere berechnung, find ich. Gefällt mir so nicht...

      Am Tag kommen da im schnitt 25.000 Beiträge dabei,wovon dann nachts wieder umgefähr die gleiche anzahl fliegt, also schon ziemlich viele daten wie ich finde.


      Also auf de Kiste läuft auch noch der Webserver, dh. 1 GB RAM für die DB (zur Zeit gesamt 1,2 GB; davon 90 MB Index). Und der stößt natürlich irgendwann an seine Grenzen aber der sollte ja so noch ein wenig mehr mit machen, oder nicht? =)

      Kommentar


      • #4
        Verschiebung per Cronjob: Joa dann hätte ich aber Tags über die Cachetable voll,
        crons können durchaus öffters ausgeführt werden...

        dann aus der Cache Table z.B.50 Einträge, das wären 3 Seiten bei 20 Beiträgen pro Seite; Dann könnt ich ab Seite 4 wieder aus der archiv table holen, unschöne sache. Die restlichen beiträge auf seite 3 aus der archivtable holen, auch doof für die weitere berechnung, find ich. Gefällt mir so nicht...
        dann nimmst du halt 40 oder 60. Die Idee mit 50 ist natürlich mehr als dumm...

        Am Tag kommen da im schnitt 25.000 Beiträge dabei,wovon dann nachts wieder umgefähr die gleiche anzahl fliegt, also schon ziemlich viele daten wie ich finde.
        sollte kein größeres problem sein.

        Kommentar


        • #5
          Original geschrieben von TobiaZ
          crons können durchaus öffters ausgeführt werden...

          dann nimmst du halt 40 oder 60. Die Idee mit 50 ist natürlich mehr als dumm...

          sollte kein größeres problem sein.
          Ja klar können die das, mal sehn irgendwie muss das ja zu lösen sein.

          ICh hab doch 60, wie oben schon steht. . Aber wenn ich nun alle X Stunden zum Beispiel die Tabellen abgleiche und rauslösche, dann hab ich irgendwann trotzdem in der ersten Tabelle z.b. nur 50 Datensätze, das heißt es sind 2 seiten mit 20 Einträgen, und eine Seite mit 10. Das sieht natürlich hässlich aus. Da müssten dann wieder 10 aus archiv tabelle ausgegeben werden damits ordenltich wirkt.. usw. Find ich umständlich.



          Naja werden aufjedenfall noch mehr Datenreduziert.

          Hab mal mit vergleichbar großen bzw. größeren Party-Communities verglichen. Die haben bei den Profilgästebüchern im Schnitt 400.000 und bei den Mails vllt. 300.000 .. Also bei uns sind die Leute aufjedenfall zu aktiv..


          Da muss halt nun geschaut werden was wichtiger ist: Dumme "hab dich lieb smile smilie smilie" Einträge oder ne ordenltiche Performance.. Und wenn ich überlege dass sich manche Leute am Tag gegenseitig 10 GB-Seiten machen, mit irgendwelchem Schund drin, entscheid ich mich lieber dazu die Daten zu kicken da sie sowieso nichts wichtiges enthalten. Und wem das alles so wichtig ist kanns ja kopieren und bei sich lokal abspeichern... =)

          Kommentar


          • #6
            Original geschrieben von haddi
            ICh hab doch 60, wie oben schon steht. . Aber wenn ich nun alle X Stunden zum Beispiel die Tabellen abgleiche und rauslösche, dann hab ich irgendwann trotzdem in der ersten Tabelle z.b. nur 50 Datensätze, das heißt es sind 2 seiten mit 20 Einträgen, und eine Seite mit 10. Das sieht natürlich hässlich aus. Da müssten dann wieder 10 aus archiv tabelle ausgegeben werden damits ordenltich wirkt.. usw. Find ich umständlich.
            meine Güte bist du unpraktikabel oO
            Dann machst du halt ein
            PHP-Code:
            $i 0;
            while (
            $row mysql_fetch_assoc($result) AND $i <= 40) {
              
            print_r($row);
              ++
            $i;

            die restlichen Einträge verfallen halt (natürlich besser mit LIMIT direkt im Query, das hier dient nur der Veranschaulichung)


            Da muss halt nun geschaut werden was wichtiger ist: Dumme "hab dich lieb smile smilie smilie" Einträge oder ne ordenltiche Performance.. Und wenn ich überlege dass sich manche Leute am Tag gegenseitig 10 GB-Seiten machen, mit irgendwelchem Schund drin, entscheid ich mich lieber dazu die Daten zu kicken da sie sowieso nichts wichtiges enthalten. Und wem das alles so wichtig ist kanns ja kopieren und bei sich lokal abspeichern... =)
            Ich verstehe sowieso momentan nicht was die Archiv-Tabelle soll ... wir sind auch eine SEHR große Community, haben das oben beschriebene Clustering (allerdings mit MOD 30, also 30 Tabellen) und die haben JEDE im Durchschnitt 450.000 Datensätze (macht also grob 13 Mio. Datensätze) ... da lahmt trotzdem nix bei der Ausgabe wenn der Index richtig gesetzt ist *shrug*

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

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

            Kommentar


            • #7
              Aber wenn ich nun alle X Stunden zum Beispiel die Tabellen abgleiche und rauslösche, dann hab ich irgendwann trotzdem in der ersten Tabelle z.b. nur 50 Datensätze, das heißt es sind 2 seiten mit 20 Einträgen, und eine Seite mit 10.
              Wieso solltest du diese situation zulassen?

              Kommentar


              • #8
                Original geschrieben von TobiaZ
                Wieso solltest du diese situation zulassen?
                Vllt. weil sich die Daten ändern?! Und um sie nicht zu zulassen hab ich ja zur Zeit dieses First in - First out. Und da kommts eben zum Gau wenn xxx User gleichzeitig GB Einträge machen:

                - Count ob Cache Table leer oder voll
                - x Einträge in die Archiv Table
                - x Einträge cache Table löschen

                und umgekehrt...




                Original geschrieben von ghostgambler
                Ich verstehe sowieso momentan nicht was die Archiv-Tabelle soll ... wir sind auch eine SEHR große Community, haben das oben beschriebene Clustering (allerdings mit MOD 30, also 30 Tabellen) und die haben JEDE im Durchschnitt 450.000 Datensätze (macht also grob 13 Mio. Datensätze) ... da lahmt trotzdem nix bei der Ausgabe wenn der Index richtig gesetzt ist *shrug*
                Jo du hast sicherlich auch mehr als einen Server zur verfügung! Zur Zeit ist da eben nur der kleine dämliche Opteron mit 1 GB RAM für Webserver UND (!) Datenbank...Und der haut ja nicht nur dummes html raus, da sind auch noch jede menge Usergalerien dabei, Eventfotos etc... Archiv Tabelle deswegen weil das Limit einfach lahm ist bei 1 Mio Datensätzen oO


                Zu den Indexenie sind richtig gesetzt...
                Zuletzt geändert von haddi; 21.11.2006, 14:56.

                Kommentar


                • #9
                  Wie ich schon sagte, mach halt einen Cronjob draus
                  Per LIMIT lässt sich die Ausgabe regulieren, auch wenn mehr Einträge in der Tabelle sind als ausgegeben werden.
                  Wenn es danach immer noch so langsam ist, solltest du vllt. mal anfangen jegliche Queries mit "EXPLAIN <query>" auf mögliche Optimierungen hin zu untersuchen

                  Vielleicht auch MySQL mal neu konfigurieren, um die Zahlen korrekt zu errechnen, bietet sich zum Beispiel sowas an:
                  http://svn.mysql.com/fisheye/browse/...cnf.linux?r=93

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

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

                  Kommentar


                  • #10
                    Original geschrieben von ghostgambler
                    Wie ich schon sagte, mach halt einen Cronjob draus
                    Per LIMIT lässt sich die Ausgabe regulieren, auch wenn mehr Einträge in der Tabelle sind als ausgegeben werden.
                    Wenn es danach immer noch so langsam ist, solltest du vllt. mal anfangen jegliche Queries mit "EXPLAIN <query>" auf mögliche Optimierungen hin zu untersuchen

                    Vielleicht auch MySQL mal neu konfigurieren, um die Zahlen korrekt zu errechnen, bietet sich zum Beispiel sowas an:
                    http://svn.mysql.com/fisheye/browse/...cnf.linux?r=93
                    Die Queries hab ich alle mit EXPLAIN optimiert.. Das isses echt nicht. Indexe stimmen wie schon gesagt auch, das passt. Wenn ich nun 20 Einträge mit Limit aus der Cache Table hole hab ich ne Queryzeit von 0,02 Sekunden, oder so. Hol ich irgendwas aus der Archiv Table, sinds direkt 2 Sekunden oder mehr.

                    Beide Tabellen absolut identisch und gleicher index, gleiche Abfrage nur anderer Tabellenname!


                    Nur ne kleine Info: Hab ne Log Table für IP Logs, brauchen wir leider. Da wird Userid, Host, IP, Zeit etc gespeichert. Hat 2 Mio. Einträge. Die Tabelle hatte nen Index - alles war arschig lahm sobald sich xx User gleichzeitig einloggten. Kaum war der Index raus -> gings flotter und keine Auslastung mehr..


                    Bei der aktuellen Hardware config komm ich wohl einfach nicht drum rum noch mehr zu beschränken und Tagsüber die Cache Table zu füllen und die Nachts aufzuräumen (= in die Archiv Table schreiben und da wieder löschen)...

                    Kommentar


                    • #11
                      Original geschrieben von haddi
                      Wenn ich nun 20 Einträge mit Limit aus der Cache Table hole hab ich ne Queryzeit von 0,02 Sekunden, oder so. Hol ich irgendwas aus der Archiv Table, sinds direkt 2 Sekunden oder mehr.
                      Klingt sehr komisch oO
                      Wie ist denn die Tabellenstruktur und der Test-Query?

                      Nur ne kleine Info: Hab ne Log Table für IP Logs, brauchen wir leider. Da wird Userid, Host, IP, Zeit etc gespeichert. Hat 2 Mio. Einträge. Die Tabelle hatte nen Index - alles war arschig lahm sobald sich xx User gleichzeitig einloggten. Kaum war der Index raus -> gings flotter und keine Auslastung mehr..
                      Um dazu was sagen zu können, müsste ich auch Struktur und Query kennen

                      Bei der aktuellen Hardware config komm ich wohl einfach nicht drum rum noch mehr zu beschränken und Tagsüber die Cache Table zu füllen und die Nachts aufzuräumen (= in die Archiv Table schreiben und da wieder löschen)...
                      Nein, du kannst auch tagsüber alle 5 Minuten die Tabelle aufräumen ... es geht nur darum komplexe Queries in Grenzen zu halten, d.h. nicht sobald das GB aufgerufen wird Verschieben (was im ungüngstigsten Fall ein paar Mal die Sekunde sein kann), sondern halt per Cron nur alle 5(/10/15/30) Minuten

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

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

                      Kommentar


                      • #12
                        Table + Index





                        Query:
                        SELECT gbid,von,nickname,zeit,eintrag,auth FROM $Table WHERE nach=USERID ORDER BY zeit DESC LIMIT X,20;


                        Absolut der einfachste Query, kein Join kein gar nichts. Alle Daten die ich brauch hol ich aus der Tabelle raus...

                        Kommentar


                        • #13
                          hm ... das "ORDER BY zeit" ist bestimmt nicht so hübsch, reicht da nicht ein "ORDER BY gbid"?
                          Und was bringt ein EXPLAIN auf den Query?
                          Ich nehme mal an, dass der Index über nach und zeit ist, ist für deinen Beispiel-Query? Wenn du nach gbid sortieren kannst, dann nimm beim nach-Key die zeit-Spalte raus, dann wird der Index kleiner und folglich auch flotter

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

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

                          Kommentar


                          • #14
                            EXPLAIN SELECT gbid, von, nickname, zeit, eintrag, auth
                            FROM gb_cache
                            WHERE nach =8679
                            ORDER BY zeit DESC
                            LIMIT 0 , 20

                            Code:
                            id  	 select_type  	 table  	 type  	 possible_keys  	 key  	 key_len  	 ref  	 rows  	 Extra
                            1 	SIMPLE 	gb_cache 	ref 	gbid 	gbid 	4 	const 	55 	Using where


                            hmm vllt doch den index auf gbid legen.

                            Kommentar


                            • #15
                              Original geschrieben von haddi
                              hmm vllt doch den index auf gbid legen.
                              Ist doch?!

                              Das Ergebnis ist eigentlich total in Ordnung ... tjo, dann musst du wirklich an anderen Stellen optimieren ^^,

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

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

                              Kommentar

                              Lädt...
                              X