steffen: MySQL Performance

Hallo zusammen,
 ich plane gerade eine Datenbank mit recht großen Datensätzen und habe zur Performance eine Frage.
Kurz zum Projekt
Es geht um eine Befragung von ca. 150-300 Fragen unterschiedlicher Anwortmöglichkeit meistes int-Werte oder Text.
Die ganze Sache findet im LAN statt, auf einem MySQL 5  Server mittels PHP. Ca. 150 Leute machen das über den Tag verteilt, bis zu 24 Personen gleichzeitig.
Die Frage und die Antworten kommen aus der db. Jetzt zur Frage.
Ist es performancemässig sinnvoll für jede Frage eine eigene Tabelle mit den Antworten aller Personen zu erstellen ?
Ist ist davon auszugehen, dass die Personen versetzt die Fragen beantworten.

  1. Hi,

    Ist es performancemässig sinnvoll für jede Frage eine eigene Tabelle mit den Antworten aller Personen zu erstellen ?

    Weder performancemässig, noch sonst irgwendwie ist dieses Vorgehen sinnvoll.

    Ohne genaue Kenntnis der Einzelheiten (wie die Fragen aufgebaut sind usw.) kann man dir keine genauen Empfehlungen zum phyiskalischen Design geben. Ins Blaue getippt: Indizes auf die Identifikation der Frage und der Person bieten sich durchaus für die Verschnellerung von Abfragen an.

    Beschäftige dich bitte mit den Prinzipien (u.a. auch Normalisierung) der relationalen Datenbankmodellierung, analysiere die Objekte/Entitäten, die bei dir eine Rolle spielen, entwickle aus deinen Erkenntnissen erst ein logisches, dann ein physikalisches Modell. Zur Info: Du hast eine Beziehung zwischen Fragen, Antwortmöglichkeiten, Personen und den Antworten.

    Ciao, Frank

    1. Moin!

      Ohne genaue Kenntnis der Einzelheiten (wie die Fragen aufgebaut sind usw.) kann man dir keine genauen Empfehlungen zum phyiskalischen Design geben. Ins Blaue getippt: Indizes auf die Identifikation der Frage und der Person bieten sich durchaus für die Verschnellerung von Abfragen an.

      Grundsätzlich kann man sagen: Indizes beschleunigen das Lesen, verlangsamen aber das Schreiben von Daten.

      Es ist daher gar nicht immer schlau, möglichst viele Indizes zu setzen.

      Andererseits hängt das Ergebnis der Abwägung natürlich auch vom Nutzungsprofil ab.

      Vollkommen blödsinnig ist aber, aufgrund von Performanceangst (die ja auch erst mal zu begründen wäre) suboptimale Datenbankstrukturen zu wählen.

      - Sven Rautenberg

      --
      "Love your nation - respect the others."
      1. Grundsätzlich kann man sagen: Indizes beschleunigen das Lesen, verlangsamen aber das Schreiben von Daten.

        Es ist daher gar nicht immer schlau, möglichst viele Indizes zu setzen.

        Das ist richtig, aber es ist m.E. fast immer schlau bei geeignetem Füllfaktor viele Indexes zu setzen.

        Vollkommen blödsinnig ist aber, aufgrund von Performanceangst (die ja auch erst mal zu begründen wäre) suboptimale Datenbankstrukturen zu wählen.

        Du meinst zum Beispiel eine Tabelle pro Frage. :)

        1. Moin!

          Grundsätzlich kann man sagen: Indizes beschleunigen das Lesen, verlangsamen aber das Schreiben von Daten.

          Es ist daher gar nicht immer schlau, möglichst viele Indizes zu setzen.

          Das ist richtig, aber es ist m.E. fast immer schlau bei geeignetem Füllfaktor viele Indexes zu setzen.

          Nein, das eben gerade nicht. Einen Index zu füllen sorgt für Mehrarbeit beim Neuschreiben von Datensätzen (INSERT und UPDATE). Nicht umsonst wird als erheblich performancesteigernd angesehen, wenn man eine Tabelle neu importieren will, dass man zunächst KEINERLEI Index auf die Tabelle legt, dann die Daten hineinschreibt, und erst nachträglich die gewünschten Indices anlegen läßt. MySQL ist schneller, wenn das Generieren des Index einmal für die gesamte Tabelle erledigt wird, anstatt bei jedem Datensatz den Index neu zu befüllen und dabei ggf. auch neu zu sortieren.

          Je mehr Indices die Tabelle hat, desto langsamer wird das Speichern. Deshalb sollte man nur die unbedingt notwendigen Indices setzen, nicht blind soviele, wie möglich.

          Wenn es tatsächlich zu Performanceproblemen kommt, ist außerdem eine Analyse der Querys notwendig. Nicht jede Spalte eignet sich wirklich für einen Index. Wenn beispielsweise eine Spalte nur zwei oder drei mögliche Werte aufweisen kann (ein ENUM mit z.B. ja/nein, männlich/weiblich o.ä.), die sich anteilsmäßig ungefähr gleich auf die Datensätze verteilen, dann bringt ein Index auf dieser Spalte keinen Vorteil, weil ein SELECT auf dieser Spalte ja trotzdem noch die Hälfte der Datensätze ergibt. Ein Full Table Scan ist da vermutlich schneller.

          Vollkommen blödsinnig ist aber, aufgrund von Performanceangst (die ja auch erst mal zu begründen wäre) suboptimale Datenbankstrukturen zu wählen.

          Du meinst zum Beispiel eine Tabelle pro Frage. :)

          Ganz genau - wobei die Performancefrage sich natürlich dann doch irgendwann stellt, wenn auf genau EINER Tabelle konkurrierende Schreib- und Lesezugriffe stattfinden sollen - und zwar gleich intensiv beides. Schreibzugriffe müssen die Tabelle für andere Schreibzugriffe sperren, damit sich nicht zwei INSERTs oder UPDATEs ins Gehege kommen. In dieser Zeit kann die Tabelle aber dann auch nicht gelesen werden. Wenn die Datenbank dann noch viel Zeit mit Indexgenerierung verbringt, entsteht irgendwann Stau.

          Aber auch dagegen ist oftmals ein Kraut gewachsen. Beispielsweise könnte man die Schreib- und Lesevorgänge voneinander trennen. Eine Originaltabelle wird dauernd beschrieben, und manchmal komplett ausgelesen, um eine Kopie in eine Lesetabelle zu schieben, die dann immer nur gelesen wird. Nachteil: In der Lesetabelle sind die Daten nicht topaktuell. Vorteil: Schreiben und Lesen kommen sich nicht in die Quere.

          Solche Lösungsansätze sucht man aber üblicherweise erst dann, wenn man tatsächlich ein Performanceproblem hat.

          - Sven Rautenberg

          --
          "Love your nation - respect the others."
          1. Das ist richtig, aber es ist m.E. fast immer schlau bei geeignetem Füllfaktor viele Indexes zu setzen.

            Nein, das eben gerade nicht. Einen Index zu füllen sorgt für Mehrarbeit beim Neuschreiben von Datensätzen (INSERT und UPDATE).

            Klar, allerdings wird bei geeignetem Füllfaktor eben nicht der ganze Index umgeschrieben, sondern dank "binären Suchens" recht gezielte Manipulationen vorgenommen. Die INSERTs werden dann nämlich nur relativ wenig zeitverzögert ausgeführt.

            Solche Lösungsansätze sucht man aber üblicherweise erst dann, wenn man tatsächlich ein Performanceproblem hat.

            Leider werden, wie Du schon sehr richtig anmerkst, diese "Sekundärüberlegungen" (also der Gedankengang und Diskussionsansatz DBDesign v. Performance) oft zu früh geführt und kosten den DBEntwickler oft wertvolle Nerven.

      2. Hallo Sven,

        vielleicht solltest du meinen Beitrag einfach noch mal genauer lesen.

        Weder habe ich was von vielen Indexen behauptet, noch davon dass sie ein Allheilmittel sind.

        Haben wir da etwas missverstanden?

        Ciao, Frank

        1. Weder habe ich was von vielen Indexen behauptet, noch davon dass sie ein Allheilmittel sind.

          Falls der Eindruck entstanden sein sollte, dass der Hamster sich für das Setzen möglichst vieler Indexe eingesetzt haben sollte, so ist auch dieser falsch. Ein Index muss natürlich auch zumindest gelegentlich von einer Abfrage benötigt werden.

          Mein Motto: When in doubt Setz Index!

          1. Moin!

            Mein Motto: When in doubt Setz Index!

            Und das ist eben nicht wirklich hilfreich - jedenfalls nicht, wenn es um Performance geht.

            - Sven Rautenberg

            --
            "Love your nation - respect the others."
        2. Moin!

          vielleicht solltest du meinen Beitrag einfach noch mal genauer lesen.

          Ich denke, dass ich das getan habe.

          Weder habe ich was von vielen Indexen behauptet, noch davon dass sie ein Allheilmittel sind.

          Das habe ich ja auch mit keiner Silbe behauptet. Ich habe dir nicht widersprochen, ich habe zusätzliche Informationen zu einem Teilaspekt deiner Antwort gegeben.

          Haben wir da etwas missverstanden?

          Ihr habt da etwas mißverstanden, ja.

          - Sven Rautenberg

          --
          "Love your nation - respect the others."
          1. Hoi,

            mit "wir" meinte ich "wir beide". Kam etwas seltsam an als direkte Antwort. Egal. Du hast Recht, ich hab Recht, alles in Butta.

            Man liest sich
            Frank

  2. Es geht um eine Befragung von ca. 150-300 Fragen unterschiedlicher Anwortmöglichkeit meistes int-Werte oder Text.

    Dann würde ich auf ein Datenbankdesign der Art

    Benutzer:
    Benutzer_ID
    Benutzer_Name
    ...                               -- weitere Angaben zum Benutzer

    Benutzer_Antworten:
    Benutzer_Antworten_ID
    Benutzer_Antworten_Benutzer_ID
    Benutzer_Antworten_Antworten_ID

    Antworten:
    Antworten_ID
    Antworten_Text
    Antworten_Text_Zaehler            -- "int-Werte"
    ...                               -- weitere Angaben zur Antwort

    Antworten_Fragen:
    Antworten_Fragen_ID
    Antworten_Fragen_Antworten_ID
    Antworten_Fragen_Fragen_ID

    Fragen:
    Fragen_ID
    Fragen_Text
    ...                               -- weitere Angaben zur Frage

    tippen wollen, d.h. Du hältst in der Tabelle "Fragen" die Fragen, in der Tabelle "Antworten" alle möglichen Antworten auf alle möglichen Fragen und in der Tabelle "Benutzer" die Benutzer. Zwischen "Benutzer" und "Antworten" sowie zwischen "Fragen" und "Antworten" scheint mir eine "n:m"-Beziehung zu bestehen.
    Ich hoffe, dass die verwendete Namensgebung intuitiv genug ist.

    Die ganze Sache findet im LAN statt, auf einem MySQL 5  Server mittels PHP. Ca. 150 Leute machen das über den Tag verteilt, bis zu 24 Personen gleichzeitig.

    Performanceprobleme sehe ich nicht, eher Implementierungsprobleme, s.o.. ;)

    Ist es performancemässig sinnvoll für jede Frage eine eigene Tabelle mit den Antworten aller Personen zu erstellen ?

    Nein, s.o..

    Ist ist davon auszugehen, dass die Personen versetzt die Fragen beantworten.

    Ja!! (man beachte das zweite "!" ;)