Eddie: Ideale Länge für einen INDEX bestimmen

Hallo allerseits,

ich brauche einen normalen Index für eine VARCHAR-Spalte. Dummerweise hat diese Spalte ein paar Millionen Einträge, ich stehe also bei der Längenangabe (die sich ja auf die ersten x indizierten Zeichen bezieht) vor der Wahl:

  • schnell + riesige Indexdatei oder
  • nicht ganz so schnell + überschaubare Indexdatei

Jetzt die Frage: wie finde ich den für mich besten Mittelweg, sprich die optimale Länge?
Trial & Error scheint mir ein bisschen zu aufwendig und laienhaft. Gibt's da nicht irgendwelche MySQL-Operationen, die mir da "Rat" geben?

Danke für eure Hilfe,
Eddie

--
Old men and far travforelers may lie with authority.
  1. Hi,

    (dumme) Gegenfrage: Wozu brauchst _du_ eine überschaubare Indexdatei? Wenn jemand damit arbeitet, dann ist es doch das Datenbanksystem, ne wahr?

    Für Backups ist es auch Wurst, da man Indizes ja theoretisch wie praktisch immer wieder neu generieren kann.

    Ausserdem, was bedeutet "riesig"?
    Und ausser-ausserdem, was hilft _dir_ der grössenoptimierte Index, wenn das Datenbanksystem dann sagt: Was will ich denn damit, da kann ich auch gleich einen Tablescan machen? sprich, ihn nicht benutzt ...

    Die "optimale" Länge des Index konvergiert mit deinen SARGs (Search Arguments) ... Also analyisiere wie durchschnittlich nah oder fern, also wie ähnlich die Millionen Einträge in der Spalte sind (der Fachbegriff fällt mir aufgrund der Uhrzeit und des Alkoholgenusses leider grad nicht ein) und ziehe eben auch in Betracht, wie du gegen die betroffe Spalte abfragst (so? %argument% ?). Vielleicht ist auch ein normaler Index nicht wirklich angebracht? Sondern du möchtest evt einen Fulltext-Index benutzen.

    So long, gut Nacht
    Frank

    1. Hallo Frank,

      Ausserdem, was bedeutet "riesig"?

      Ca. 600 MB, 6.500.000 Einträge.

      Und ausser-ausserdem, was hilft _dir_ der grössenoptimierte Index, wenn das Datenbanksystem dann sagt: Was will ich denn damit, da kann ich auch gleich einen Tablescan machen? sprich, ihn nicht benutzt ...

      Unter welchen Umständen passiert sowas?

      Die "optimale" Länge des Index konvergiert mit deinen SARGs (Search Arguments) ... Also analyisiere wie durchschnittlich nah oder fern, also wie ähnlich die Millionen Einträge in der Spalte sind (der Fachbegriff fällt mir aufgrund der Uhrzeit und des Alkoholgenusses leider grad nicht ein)

      Die DB enthält Ortsnamen aus aller Welt: ich gehe also davon aus, dass bei den ersten Zeichen eine maximale Streuung vorliegt. Da aber natürlich die meisten Namen nicht die maximale Länge (nämlich 196 Zeichen) erreichen, nimmt die Streuung nach hinten logischerweise ab. Darum würde so ein längenbegrenzter Index vielleicht schon Sinn machen. Stell ich mir zumindest so vor.

      und ziehe eben auch in Betracht, wie du gegen die betroffe Spalte abfragst (so? %argument% ?). Vielleicht ist auch ein normaler Index nicht wirklich angebracht? Sondern du möchtest evt einen Fulltext-Index benutzen.

      Ich frage mittels LIKE 'Suchwort%' ab, ein normaler Index genügt also.

      Eddie

      --
      Old men and far travelers may lie with authority.
      1. yo,

        Und ausser-ausserdem, was hilft _dir_ der grössenoptimierte Index, wenn das Datenbanksystem dann sagt: Was will ich denn damit, da kann ich auch gleich einen Tablescan machen? sprich, ihn nicht benutzt ...
        Unter welchen Umständen passiert sowas?

        zum beispiel wenn die ergebnismenge 10% der gesamtgröße der tabelle übersteigt oder aber je nachdem, wie die kardinalität der datenbank beschaffen ist, sprich gleichen sich viele werte in der entsprechen tabelle oder nicht. ein b-tree index hätte zum beispiel damit probleme, wenn viele werte sich gar nicht unterscheiden.

        Die DB enthält Ortsnamen aus aller Welt: ich gehe also davon aus, dass bei den ersten Zeichen eine maximale Streuung vorliegt. Da aber natürlich die meisten Namen nicht die maximale Länge (nämlich 196 Zeichen) erreichen, nimmt die Streuung nach hinten logischerweise ab. Darum würde so ein längenbegrenzter Index vielleicht schon Sinn machen. Stell ich mir zumindest so vor.

        ja, das kann durchaus sinn machen, den index kleiner zu halten und dml anweisungen zu beschleunigen. es gibt aber eine goldene regel beim datenbank-tuning, "probieren geht über studieren". so mancher experte hat sich schon gewundert, welch grosser unterschied zwischen seiner annahme und dem tatsächlichen ergebnis es gab. sprich, nimm einfach einen wert, der dir geeignet erscheint, schaue dir die geschwindigkeit der abfragen und den ausführungsplan an. ist es zu langsam, erhöhst du die indexlänge, ist es schnell gehts du weiter runter, bis du deinen wert gefunden hast.

        Ilja

      2. "Darum würde so ein längenbegrenzter Index vielleicht schon Sinn machen. Stell ich mir zumindest so vor."

        Welche Indexgrössen erreichst Du denn bei "voller" Indizierung und welche, wenn Du nur die sagen wir mal ersten 10 Zeichen indizieren lässt?

  2. Jetzt die Frage: wie finde ich den für mich besten Mittelweg, sprich die optimale Länge?

    Ich setze immer ganz doof einen Index und kenne die von Dir skizzierten Einstellungen so gar nicht.
    Was ich mache ist auf das voraussichtliche Datenzugriffsverhalten zu achten, also sind die Daten "read only", dann setze ich einen Index ohne Füllfaktor, ist mit vielen INSERTs zu rechnen einen mit Füllfaktor, ist mit keinen SELECTs zu rechnen, keinen Index.   ;)

    Trial & Error scheint mir ein bisschen zu aufwendig und laienhaft. Gibt's da nicht irgendwelche MySQL-Operationen, die mir da "Rat" geben?

    Was schreibt die Doku zu diesem Index-fine tuning?