MariaDB
 sql >> Datenbank >  >> RDS >> MariaDB

Indizes in MySQL verstehen:Teil Eins

Indizes in MySQL sind ein sehr komplexes Ungetüm. Wir haben in der Vergangenheit MySQL-Indizes behandelt, aber wir sind noch nie tiefer in sie eingetaucht – das werden wir in dieser Reihe von Blog-Beiträgen tun. Dieser Blogbeitrag soll als sehr allgemeiner Leitfaden für Indizes dienen, während die anderen Teile dieser Serie etwas tiefer in diese Themen eintauchen.

Was sind Indizes?

Im Allgemeinen ist ein Index, wie bereits in einem früheren Blogbeitrag über Indizes erwähnt, eine alphabetische Liste von Datensätzen mit Verweisen auf die Seiten, auf denen sie erwähnt werden. In MySQL ist ein Index eine Datenstruktur, die am häufigsten verwendet wird, um Zeilen schnell zu finden. Möglicherweise hören Sie auch den Begriff „Schlüssel“ – er bezieht sich auch auf Indizes.

Was machen Indizes?

In MySQL werden Indizes verwendet, um Zeilen mit bestimmten Spaltenwerten schnell zu finden und zu verhindern, dass die gesamte Tabelle durchgelesen wird, um für die Abfrage relevante Zeilen zu finden. Indizes werden meistens verwendet, wenn die in einem Datenbanksystem (z. B. MySQL) gespeicherten Daten größer werden, denn je größer die Tabelle ist, desto größer ist die Wahrscheinlichkeit, dass Sie von Indizes profitieren könnten.

MySQL-Indextypen

Soweit es MySQL betrifft, haben Sie vielleicht schon davon gehört, dass es mehrere Arten von Indizes gibt:

  • Ein B-Baum-INDEX - ein solcher Index wird häufig verwendet, um SELECT-Abfragen zu beschleunigen, die mit einer WHERE-Klausel übereinstimmen. Ein solcher Index kann für Felder verwendet werden, in denen Werte nicht eindeutig sein müssen, er akzeptiert auch NULL-Werte.

  • EIN VOLLTEXTINDEX - ein solcher Index wird verwendet, um Volltextsuchfunktionen zu nutzen. Diese Art von Index findet Schlüsselwörter im Text, anstatt Werte direkt mit den Werten im Index zu vergleichen.

  • EIN EINZIGARTIGER INDEX wird häufig verwendet, um doppelte Werte aus einer Tabelle zu entfernen. Erzwingt die Eindeutigkeit von Zeilenwerten.

  • Ein PRIMARY KEY ist auch ein Index – er wird häufig zusammen mit Feldern mit einem AUTO_INCREMENT-Attribut verwendet. Dieser Indextyp akzeptiert keine NULL-Werte und einmal festgelegt, können die Werte in der Spalte, die einen PRIMARY KEY hat, nicht mehr geändert werden.

  • Ein absteigender Index ist ein Index, der Zeilen in absteigender Reihenfolge speichert. Dieser Indextyp wurde in MySQL 8.0 eingeführt - MySQL verwendet diesen Indextyp, wenn eine absteigende Reihenfolge von der Abfrage angefordert wird.

Auswahl optimaler Datentypen für Indizes in MySQL

Soweit Indizes betroffen sind, muss man auch bedenken, dass MySQL eine Vielzahl von Datentypen unterstützt und einige Datentypen nicht zusammen mit bestimmten Arten von Indizes verwendet werden können (z. B. FULLTEXT Indizes können nur für textbasierte Spalten (CHAR, VARCHAR oder TEXT) verwendet werden – sie können nicht für andere Datentypen verwendet werden), also entscheiden Sie sich vor der tatsächlichen Auswahl der Indizes für Ihr Datenbankdesign für den Datentyp, den Sie verwenden möchten die fragliche Spalte (entscheiden Sie, welche Art von Datenklasse Sie speichern werden:Werden Sie Zahlen speichern? Zeichenfolgenwerte? Sowohl Zahlen als auch Zeichenfolgenwerte? usw.), und entscheiden Sie sich dann für den Bereich der Werte, die Sie speichern möchten (Wählen Sie denjenigen aus, den Sie Ihrer Meinung nach nicht überschreiten werden, da das Erweitern des Datentypbereichs später eine zeitaufwändige Aufgabe sein kann - wir empfehlen Ihnen, sich für die Verwendung eines einfachen Datentyps zu entscheiden), und wenn Sie nicht beabsichtigen, NULL zu verwenden Werte in Ihren Spalten, geben Sie Ihre Felder wann immer möglich als NOT NULL an - wenn ein nullable co lumn indiziert ist, benötigt es ein zusätzliches Byte pro Eintrag.

Auswahl optimaler Zeichensätze und Sortierungen für Indizes in MySQL

Abgesehen von den Datentypen sollten Sie auch bedenken, dass jedes Zeichen in MySQL Platz beansprucht. Beispielsweise können UTF-8-Zeichen jeweils zwischen 1 und 4 Byte umfassen, sodass Sie die Indizierung von beispielsweise 255 Zeichen vermeiden und beispielsweise nur 50 oder 100 Zeichen für eine bestimmte Spalte verwenden möchten.

Die Vor- und Nachteile der Verwendung von Indizes in MySQL

Der Hauptvorteil der Verwendung von Indizes in MySQL ist die gesteigerte Leistung von Suchanfragen, die mit einer WHERE-Klausel übereinstimmen - Indizes beschleunigen SELECT-Abfragen, die mit einer WHERE-Klausel übereinstimmen, da MySQL nicht die gesamte Tabelle durchliest, um Zeilen zu finden für die Abfrage relevant. Beachten Sie jedoch, dass Indizes ihre eigenen Nachteile haben. Die wichtigsten sind wie folgt:

  • Indizes verbrauchen Speicherplatz.

  • Indexe verschlechtern die Leistung von INSERT-, UPDATE- und DELETE-Abfragen - wenn Daten aktualisiert werden, muss der Index aktualisiert werden zusammen mit ihm aktualisiert.

  • MySQL schützt Sie nicht davor, mehrere Arten von Indizes gleichzeitig zu verwenden. Mit anderen Worten, Sie können einen PRIMARY KEY, einen INDEX und einen UNIQUE INDEX für dieselbe Spalte verwenden - MySQL schützt Sie nicht vor einem solchen Fehler.

Wenn Sie vermuten, dass einige Ihrer Abfragen langsamer werden, sollten Sie einen Blick in die Registerkarte "Abfragemonitor" von ClusterControl werfen - durch Aktivieren des Abfragemonitors können Sie sehen, wann eine bestimmte Abfrage zuletzt gesehen wurde und wie hoch sie war und durchschnittliche Ausführungszeit, die Ihnen helfen können, die besten Indizes für Ihre Tabelle auszuwählen.

Wie wähle ich den besten Index aus?

Um den besten zu verwendenden Index auszuwählen, können Sie die integrierten Mechanismen von MySQL verwenden. Beispielsweise können Sie den Abfrageerklärer verwenden – die EXPLAIN-Abfrage. Es wird erklärt, welche Tabelle verwendet wird, ob sie Partitionen hat oder nicht, welche Indizes verwendet werden können und welcher Schlüssel (Index) verwendet wird. Es gibt auch die Indexlänge und die Anzahl der Zeilen zurück, die Ihre Abfrage zurückgibt:

mysql> EXPLAIN SELECT * FROM demo_table WHERE demo_field = ‘demo’\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: demo_table
   partitions: NULL
         type: ref
possible_keys: demo_field
          key: demo_field
      key_len: 1022
          ref: const
         rows: 1
     filtered: 100.00
        Extra: NULL
1 row in set, 1 warning (0.00 sec)

Beachten Sie in diesem Fall, dass Indizes häufig verwendet werden, um MySQL dabei zu helfen, Daten effizient abzurufen, wenn Datensätze größer als gewöhnlich sind. Wenn Ihre Tabelle klein ist, müssen Sie möglicherweise keine Indizes verwenden, aber wenn Sie feststellen, dass Ihre Tabellen immer größer und größer werden, könnten Sie von einem Index profitieren.

Beachten Sie bei der Auswahl des besten Index für Ihr spezifisches Szenario jedoch, dass Indizes auch eine Hauptursache für Leistungsprobleme sein können. Denken Sie daran, dass es von einigen Faktoren abhängt, ob MySQL die Indizes effektiv verwendet oder nicht, darunter das Design Ihrer Abfragen, die verwendeten Indizes, die verwendeten Indextypen sowie Ihre Datenbanklast zum Zeitpunkt der Ausführung der Abfrage und andere Dinge. Hier sind ein paar Dinge, die Sie bei der Verwendung von Indizes in MySQL beachten sollten:

  • Wie viele Daten haben Sie? Vielleicht ist einiges davon überflüssig?

  • Welche Abfragen verwenden Sie? Würden Ihre Abfragen LIKE-Klauseln verwenden? Was ist mit der Bestellung?

  • Welche Art von Index müssten Sie verwenden, um die Leistung Ihrer Abfragen zu verbessern?

  • Sollen Ihre Indizes groß oder klein sein? Müssen Sie einen Index für ein Präfix der Spalte verwenden, um sie kleiner zu machen?

Es ist erwähnenswert, dass Sie wahrscheinlich auch vermeiden sollten, mehrere Arten von Indizes (z. B. einen B-Tree-Index, einen UNIQUE INDEX und einen PRIMARY KEY) für dieselbe Spalte zu verwenden.

Verbessern der Abfrageleistung mit Indizes

Um die Abfrageleistung mit Indizes zu verbessern, müssen Sie sich Ihre Abfragen ansehen - die EXPLAIN-Anweisung kann dabei helfen. Im Allgemeinen sollten Sie Folgendes beachten, wenn Sie möchten, dass Ihre Indizes die Leistung Ihrer Abfragen verbessern:

  • Fragen Sie die Datenbank nur nach dem, was Sie brauchen. In den meisten Fällen ist die Verwendung von SELECT-Spalten schneller als die Verwendung von SELECT * (das ist der Fall, ohne auch Indizes zu verwenden)

  • Ein B-Tree-Index könnte passen, wenn Sie nach genauen Werten suchen (z. B. SELECT * FROM demo_table WHERE some_field ='x') oder wenn Sie mit Platzhaltern nach Werten suchen möchten (z. B. SELECT * FROM demo_table WHERE some_field LIKE 'demo%' - denken Sie in diesem Fall daran, dass die Verwendung von LIKE-Abfragen mit irgendetwas am Anfang ausreichen könnte mehr schadet als nützt - vermeiden Sie die Verwendung von LIKE-Abfragen mit einem Prozentzeichen vor dem gesuchten Text - auf diese Weise verwendet MySQL möglicherweise keinen Index, da es nicht weiß, womit der Zeilenwert beginnt) - denken Sie jedoch daran dass ein B-Tree-Index auch für Spaltenvergleiche in Ausdrücken verwendet werden kann, die gleich (=), größer als (>), größer oder gleich (>=), kleiner als (<), kleiner oder gleich verwenden (<=) oder BETWEEN-Operatoren.

  • Ein FULLTEXT-Index könnte geeignet sein, wenn Sie Volltext verwenden (MATCH ... AGAINST( )) Suchanfragen oder wenn Ihre Datenbank so konzipiert ist, dass sie nur textbasierte Spalten verwendet - FULLTEXT-Indizes können TEXT-, CHAR- oder VARCHAR-Spalten verwenden, sie können nicht für andere Spaltentypen verwendet werden.

  • Ein abdeckender Index kann nützlich sein, wenn Sie Abfragen ohne zusätzliche I/O-Lesezugriffe auf große Tabellen ausführen möchten . Um einen abdeckenden Index zu erstellen, decken Sie die Klauseln WHERE, GROUP BY und SELECT ab, die von der Abfrage verwendet werden.

Wir werden uns in den kommenden Teilen dieser Blogserie weiter mit den Arten von Indizes befassen, aber im Allgemeinen, wenn Sie Abfragen wie SELECT * FROM demo_table WHERE some_field ='x' verwenden, ist ein B-Baum-INDEX könnte passen, wenn Sie MATCH() AGAINST() Abfragen verwenden, sollten Sie wahrscheinlich in einen FULLTEXT-Index schauen, wenn Ihre Tabelle sehr lange Zeilenwerte hat, sollten Sie wahrscheinlich einen Teil der Spalte indizieren.

Wie viele Indizes sollten Sie haben?

Wenn Sie jemals Indizes verwendet haben, um die Leistung Ihrer SELECT-Abfragen zu verbessern, haben Sie sich wahrscheinlich eine Frage gestellt:Wie viele Indizes sollten Sie eigentlich haben? Um dies zu verstehen, müssen Sie Folgendes beachten:

  1. Indizes sind normalerweise am effektivsten bei großen Datenmengen.

  2. MySQL verwendet nur einen Index pro SELECT-Anweisung in einer Abfrage (Unterabfragen werden als separate Anweisungen angesehen) - use die EXPLAIN-Abfrage, um herauszufinden, welche Indizes für die von Ihnen verwendeten Abfragen am effektivsten sind.

  3. Indizes sollten alle Ihre SELECT-Anweisungen schnell genug machen, ohne zu viel Speicherplatz zu gefährden - „schnell genug“ , ist jedoch relativ, also müssten Sie experimentieren.

Indizes und Speicher-Engines

Beachten Sie beim Umgang mit Indizes in MySQL auch, dass es einige Einschränkungen geben kann, wenn Sie verschiedene Engines verwenden (z. B. wenn Sie MyISAM anstelle von InnoDB verwenden). Wir werden in einem separaten Blog näher darauf eingehen, aber hier sind einige Ideen:

  • Die maximale Anzahl von Indizes pro MyISAM- und InnoDB-Tabellen ist 64, die maximale Anzahl von Spalten pro Index in beiden Speicher-Engines ist 16.

  • Die maximale Schlüssellänge für InnoDB beträgt 3500 Bytes - die maximale Schlüssellänge für MyISAM beträgt 1000 Bytes.

  • Die Volltextindizes haben Einschränkungen in bestimmten Speicher-Engines – zum Beispiel haben die InnoDB-Volltextindizes 36 Stoppwörter, MyISAM Die Stoppwortliste ist mit 143 Stoppwörtern etwas größer. InnoDB leitet diese Stoppwörter von der Variable innodb_ft_server_stopword_table ab, während MyISAM diese Stoppwörter von der Datei storage/myisam/ft_static.c ableitet – alle Wörter, die in der Datei gefunden werden, werden als Stoppwörter behandelt.

  • MyISAM war die einzige Speicher-Engine mit Unterstützung für Volltextsuchoptionen bis MySQL 5.6 (MySQL 5.6. 4 um genau zu sein) kam dazu, was bedeutet, dass InnoDB seit MySQL 5.6.4 Volltextindizes unterstützt. Wenn ein FULLTEXT-Index verwendet wird, findet er Schlüsselwörter im Text, anstatt Werte direkt mit den Werten im Index zu vergleichen.

  • Indizes spielen eine sehr wichtige Rolle für InnoDB - InnoDB sperrt Zeilen, wenn es darauf zugreift, also eine reduzierte Anzahl von Zeilen InnoDB-Zugriffe können Sperren reduzieren.

  • MySQL ermöglicht es Ihnen, doppelte Indizes für dieselbe Spalte zu verwenden.

  • Bestimmte Speicher-Engines haben bestimmte Standardtypen von Indizes (z. B. für die Speicher-Engine MEMORY ist der Standard-Indextyp Hash )

Zusammenfassung

In diesem Teil über Indizes in MySQL sind wir einige allgemeine Dinge im Zusammenhang mit Indizes in diesem relationalen Datenbankverwaltungssystem durchgegangen. In den kommenden Blogbeiträgen werden wir einige eingehendere Szenarien der Verwendung von Indizes in MySQL durchgehen, einschließlich der Verwendung von Indizes in bestimmten Speicher-Engines usw. - wir werden auch erklären, wie ClusterControl verwendet werden kann, um Ihre Leistungsziele in MySQL zu erreichen.