2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Inhaltsverzeichnis
Welche Art von Feldern wählen wir normalerweise zum Erstellen von Indizes aus?
Was ist das Leftmost-Matching-Prinzip?
Ganz links übereinstimmende Prinzipabfragereihenfolge
Was ist Index-Pushdown? In MySQL5.6 hinzugefügt, um Datenabfragen zu optimieren
Wie erstelle ich einen Index, bei dem a>1 und b=2 und c <3 ist?
(A,B,C) gemeinsamer Index * aus TBN auswählen, wobei a=? und b in (?,?) und c>?
Wie erstelle ich einen gemeinsamen Index mit a>100 und b=100 und c=123, sortiert nach d?
Ich habe erfahren, dass MySQL dies getan hatPrimärschlüsselIndex, eindeutiger Index, gewöhnlicher Index, Präfixindex,GewerkschaftsindexDiese Arten von Indizes.
Die Innodb-Engine erfordert, dass jede Datenbanktabelle eine haben mussPrimärschlüsselIndex,Indexspaltenwerte sind nicht zulässigNullwert。Beispielsweise ist das ID-Feld in der Tabelle der Primärschlüsselindex
Eindeutiger Index: Stellen Sie die Eindeutigkeit jeder Datenzeile in der Datenspalte sicher, lassen Sie jedoch Nullwerte zu.
DannFür Felder, die häufig abgefragt werden, können wir einen normalen Index für dieses Feld erstellen.,Wenn mehrere Felder vorhanden sind, können Sie die Erstellung in Betracht ziehenGewerkschaftsindex,verwendenIndexabdeckungFunktionen verbessern die Abfrageeffizienz.
Für Langtexte, Zeichenfolgen und andere Arten von Feldern wie Artikeltitel, Produktnamen usw. können wir also nur den Präfixteil dieser Felder indizierenErstellen Sie einen Präfixindex, um den Speicherplatz des Index zu reduzieren.
Ein eindeutiger Index ist möglicherweise etwas schneller, wenn ein einzelner Wert abgefragt wird, da er die Suche beenden kann, nachdem die erste Übereinstimmung gefunden wurde.
Bei Einfüge- und Aktualisierungsvorgängen ist ein normaler Index möglicherweise etwas schneller, da keine Eindeutigkeitsprüfungen erforderlich sind.
Die Werte gewöhnlicher Indexspalten können wiederholt werden, aber die Werte eindeutiger Indexspalten müssen eindeutig sein. Wenn wir einen wiederholten Wert in einen eindeutigen Index einfügen, wird aufgrund der Eindeutigkeitsbeschränkung ein Fehler gemeldet.
Ich findeDie Aktualisierungsleistung des normalen Index ist besser, da die Datenseite nicht aktualisiert wird, wenn der normale Index aktualisiert wirdErinnerung Wenn dies der Fall ist, können Sie den Aktualisierungsvorgang direkt im Änderungspuffer zwischenspeichern und der Aktualisierungsvorgang wird abgeschlossen. (keine Eindeutigkeitsprüfung erforderlich)
Aber,Der eindeutige Index muss eindeutige Einschränkungen haben. Wenn sich die aktualisierte Datenseite nicht im befindetErinnerungWenn dies der Fall ist, müssen Sie die entsprechende Datenseite von der Festplatte in den Speicher lesen, um festzustellen, ob ein Konflikt vorliegt. Dies erfordert eine Festplatten-Randomisierung.IOZugang.
Da normale Indizes die Änderungspufferfunktion verwenden können, erfolgt die Aktualisierung gewöhnlicher Indizes schneller als die Aktualisierung eindeutiger Indizes.Reduzierter zufälliger Festplattenzugriff, sodass die Aktualisierungsleistung besser ist
Wenn InnoDB einen Clustered-Index erstellt, wählt es je nach Szenario unterschiedliche Spalten als Indizes aus:
Wenn ein Primärschlüssel vorhanden ist, wird dieser standardmäßig als Indexschlüssel des Clustered-Index verwendet.
Wenn kein Primärschlüssel vorhanden ist, wählen Sie ausDer erste enthält nicht NULL-WertDie einzige Spalte von ist asClustered-IndexIndexschlüssel
Fehlt einer der oben genannten Punkte, generiert InnoDB automatisch eine implizite, automatisch inkrementierende RowID-Spalte als Indexschlüssel des Clustered-Index.
Szenarien, in denen eine Indizierung anwendbar ist:
Für Felder gelten Eindeutigkeitsbeschränkungen, wie z. B. Produktcode
Felder, die häufig in WHERE-Abfragebedingungen verwendet werden, was die Abfragegeschwindigkeit der gesamten Tabelle verbessern kann. Wenn die Abfragebedingung kein Feld ist, kann ein gemeinsamer Index erstellt werden
Felder, die häufig in GROUPBY und ORDER BY verwendet werden, sodass bei der Suche keine erneute Sortierung erforderlich ist, da alle Datensätze im B+-Baum nach der Indexerstellung sortiert werden.
Szenarien, die nicht für die Indizierung geeignet sind
Felder, die nicht in WHERE-Bedingungen, GROUP BY, ORDER BY verwendet werden, Der Wert des Index ist eine schnelle Positionierung. Wenn das Feld nicht positioniert werden kann, ist es normalerweise nicht erforderlich, einen Index zu erstellen, da der Index physischen Platz einnimmt.
Felder mit geringer Unterscheidungskraft Es ist nicht erforderlich, einen Index zu erstellen. Das Geschlechtsfeld enthält beispielsweise nur Männer und Frauen. Wenn die Datensätze von Männern und Frauen gleichmäßig in der Datenbanktabelle verteilt sind, kann es sein, dass die Hälfte der Daten unabhängig vom gesuchten Wert vorhanden ist erhalten werden.In diesen Fällen ist es besser, nicht zu indizieren, weil MySQLEs gibt noch einenAbfrageoptimiererWenn der Abfrageoptimierer feststellt, dass ein bestimmter Wert in einem hohen Prozentsatz der Datenzeilen in der Tabelle vorkommt, ignoriert er im Allgemeinen den Index und führt ihn ausVollständiger Tabellenscan。
Häufig aktualisierte FelderBeispielsweise wird die Benutzerbilanz von E-Commerce-Projekten nicht indiziert, da die Indexfelder häufig geändert werden.aufrecht erhalten B+BaumWenn die Ordnungsmäßigkeit gewährleistet ist, ist eine häufige Neuerstellung des Index erforderlich, und dieser Vorgang wirkt sich auf die Datenbankleistung aus.
Es wird nicht empfohlen, ungeordnete Werte zu verwenden(z. B. Personalausweis, UUID) als Index. Wenn der Primärschlüssel unsicher ist, führt dies zu einer häufigen Aufteilung der Blattknoten und einer Fragmentierung des Festplattenspeichers.
Die Datentabelle ist kleiner: Wenn die Datenmenge in einer Tabelle gering ist oder wenn eine Abfrage das Scannen eines großen Teils der Daten in der Tabelle erfordert, wählt der Datenbankoptimierer möglicherweise einen vollständigen Tabellenscan anstelle der Verwendung eines Index. In diesem Fall können die Kosten für die Pflege des Index größer sein als der Leistungsgewinn.
Nein, obwohl Indizes die Abfrageeffizienz verbessern können, bedeutet das Erstellen eines weiteren Index, dass ein neuer B+-Baumindex generiert wird, der Speicherplatz beansprucht. Insbesondere wenn die Menge an Tabellendaten sehr groß ist, nimmt der Index mehr Platz ein.
Je mehr Indizes vorhanden sind, desto geringer ist die Schreibleistung der Datenbank, da jedes Mal, wenn Sie die Tabelle hinzufügen, löschen oder ändern, die Reihenfolge jedes B+-Baumindex beibehalten werden muss.
Ich habe diese Optimierungsmethoden verwendet
Für SQL, das Daten in mehreren Feldern abfragen muss, können wir erstellenGewerkschaftsindex, also wird die Abfragemethodeabdeckender IndexDadurch wird die Tabellenunterstützung vermieden und eine große Anzahl von E/A-Vorgängen reduziert.
unserPrimärschlüsselIndizes sind vorzugsweise steigende WerteDa unser Index die Daten in der richtigen Reihenfolge speichert, kann es zu einer Seitenaufteilung kommen, wenn der Wert des Primärschlüssels ein Zufallswert ist, was zu einer großen Anzahl von Speicherfragmenten führt, sodass die Indexstruktur nicht kompakt ist Auswirkungen auf die Abfrageeffizienz haben.
wir wollenVermeiden Sie das Ausschreiben von Indexfehlern SQL Anweisungen wie „Kein Links- oder Links-Fuzzy-Matching für Indexspalten“ führen keine Berechnungen, Funktionen und Typkonvertierungsoperationen für Indizes durch. Um gemeinsame Indizes korrekt zu verwenden, müssen Sie das Prinzip des Linksvergleichs usw. befolgen.Wenn in der WHERE-Klausel die Bedingungsspalte vor dem OR eine Indexspalte und die Bedingungsspalte nach dem OR keine Indexspalte ist, schlägt der Index fehl.
Verwendung ungleich (
<>
) oder NOT-Operator: Diese Operatoren machen normalerweise den Index ungültig, da sie die gesamte Tabelle scannen.OR-Operator: Wenn OR in der Abfragebedingung verwendet wird und die Bedingungen auf beiden Seiten des OR unterschiedliche Indizes beinhalten, dürfen diese Indizes nicht verwendet werden.
verwenden
OR
Betreiber, wennOR
Die Bedingungen auf beiden Seiten beinhalten unterschiedliche Indizes, und das Datenbankmodul kann in den meisten Fällen nicht mehrere Indizes gleichzeitig verwenden, um die Abfrage zu optimieren.Das istWeilOR
Der Bediener muss nur die Bedingungen auf beiden Seiten erfüllen, was die Komplexität der Abfrageoptimierung erhöht.
Index für eine große Zeichenfolge, können wir über die Verwendung nachdenkenPräfixindexNur der Präfixteil der Indexspalte wird indiziert, um Indexspeicherplatz zu sparen und die Abfrageleistung zu verbessern.
Index wird am besten auf NOT gesetzt NULL : Um den Index besser nutzen zu können, sollte die Indexspalte auf die Einschränkung NOT NULL gesetzt werden. Es gibt zwei Gründe:
Das Vorhandensein von NULL in Indexspalten macht die Indexauswahl des Optimierers komplizierter und erschwert die Optimierung von Vorgängen wie der Zählung.
Der NULL-Wert ist ein bedeutungsloser Wert, der jedoch physischen Platz einnimmt. Es gibt eine Nullwertspalte.Zum Speichern von NULL wird mindestens 1 Byte Speicherplatz verwendet Liste von Werten
NEIN.
Ich habe gelerntAuch wenn die Abfrage einen Index verwendet, kann es sein, dass sie den Index nicht verwendet.
Beispiel: Wenn unsere Abfrageanweisung Links-Fuzzy-Matching, Ausdrucksberechnung, Funktion und implizite Typkonvertierungsvorgänge für das Indexfeld durchführt, kann die Abfrageanweisung den Index nicht durchlaufen und die Abfragemethode wird zu einem vollständigen Tabellenscan.
Und wir nutzenGewerkschaftsindexWenn bei der Abfrage das Übereinstimmungsprinzip ganz links nicht befolgt wird, tritt auch ein Indexfehler auf.。
Der Optimierer istWählen Sie eine Abfragemethode basierend auf KostenüberlegungenWenn der Sekundärindex für die Abfrage verwendet wird, berechnet der Optimierer die Kosten für die Tabellenrückgabe und die Kosten für den vollständigen Tabellenscan. Wenn die Kosten für die Tabellenrückgabe zu hoch sind, entscheidet sich der Optimierer dafür, den Index nicht zu verwenden, sondern den Vollständiger Tabellenscan.
Wird den Index nicht erreichen.
Weil MySQL auftrittString- und Zahlenvergleichwird passieren, wannimplizite Typkonvertierung, WilleKonvertieren Sie ein String-Objekt in eine Zahl, dieser Konvertierungsprozess beinhaltet tatsächlichFunktion . In der von Ihnen erwähnten Abfrage ist das Datumsfeld eine Zeichenfolge. Wenn also eine implizite Typkonvertierung erfolgt, wird sie auf das Datumsindexfeld angewendet. Wenn eine Funktionsberechnung für den Index durchgeführt wird, wird der Index ungültig.
Zum Beispiel für Indexspalten vom Typ Integer
id
Spalte, deren Wert direkt im Index gespeichert wird, ohne dass eine Funktionsberechnung erfolgt.Dies bedeutet die Verwendung in der Abfrageid
Beim Matching ist dies nicht erforderlichid
Führen Sie beliebige funktionale Berechnungen oder Konvertierungen durch und vergleichen Sie einfach ganzzahlige Werte.
Ich habe gelernt, dass MySQL8.0 Felder hinzufügen kannFunktionsindexDiese neue Funktion kann das Problem des Indexfehlers bei der Verwendung von Funktionen im Index lösen.
Eine weitere neue Funktion istIndex-Scan überspringenWenn vor Version 5.7 ein gemeinsamer Index verwendet wird und das Übereinstimmungsprinzip ganz links nicht erfüllt ist, tritt ein Indexfehler auf. Nach der Einführung der Index-Skip-Scan-Funktion in 8.0 können gemeinsame Indizes jedoch weiterhin verwendet werden, selbst wenn das Übereinstimmungsprinzip ganz links verwendet wird wird nicht befolgt.
Angenommen, es gibt einen gemeinsamen Index (a, b, c). Seine Speicherreihenfolge besteht darin, zuerst nach a zu sortieren, dann nach b zu sortieren, wenn a gleich ist, und dann nach c zu sortieren, wenn b gleich ist. Aufgrund dieser Funktion gilt bei der Verwendung gemeinsamer Indizes das Prinzip der Linksübereinstimmung. Die spezifischen Regeln sind:
Der föderierte Index von MySQL beginnt mitDie Indexspalte ganz links beginnt mit der Übereinstimmung mit den Abfragebedingungen und stimmt dann der Reihe nach von links nach rechts überein. Wenn die Abfragebedingungen keine Spalte verwenden, können nicht alle Spalten rechts von der Spalte indiziert werden.
Wenn eine Spalte in der Abfragebedingung verwendet wird,Der Wert dieser Spalte enthält jedoch eine Bereichsabfrage und die Felder der Bereichsabfrage können verwendet werdenGewerkschaftsindex, aber der gemeinsame Index kann nicht in den Feldern hinter dem Bereichsabfragefeld verwendet werden.
Wenn wir gemeinsame Indizes verwenden, müssen wir uns daher an das Prinzip der Übereinstimmung ganz links halten, da sonst einige Indexfelder möglicherweise nicht indiziert werden.
am meistenTragen Sie die Felder mit der größeren Unterscheidung einGewerkschaftsindexganz links, hilfreichVerbessern Sie den Indexfiltereffekt, Felder wie UUID eignen sich besser für die Indizierung oder Rangfolge oben in der gemeinsamen Indexspalte.
Wenn ein Feld mit geringer Unterscheidung ganz links im gemeinsamen Index platziert wird, kann dies dazu führen, dass der Abfrageoptimierer einen vollständigen Tabellenscan auswählt, anstatt den Index zu verwenden.
Das am weitesten links stehende Matching-Prinzip des gemeinsamen Index, inWenn eine Bereichsabfrage auftritt (z. B. >, <), wird der Abgleich beendetDas heißt, die Felder der Bereichsabfrage können den gemeinsamen Index verwenden, die Felder hinter dem Bereichsabfragefeld jedoch nicht den gemeinsamen Index.Bei den vier Bereichsabfragen >=, <=, BETWEEN und ähnlichem Präfixabgleich wird der Abgleich jedoch nicht beendet.
In MySQL enthält BETWEEN die Grenzwerte value1 und value2, ähnlich wie >= und =<.
Referenzlink https://zhuanlan.zhihu.com/p/573138586
select * from T where c=1 and a=2 and b=3;
abc kann indiziert werden, weil Die Reihenfolge der Abfragebedingungsfelder hat keinen Einfluss, hilft uns der MySQL-Optimierer dabei, die Abfragereihenfolge der Felder so anzupassen, dass er auch dem Prinzip der Übereinstimmung ganz links entspricht.
Der Index-Pushdown kann reduziert werdenSekundärindexDer Tabellenrückgabevorgang während der Abfrage verbessert die Abfrageeffizienz, da dies der Fall ist Die Serverschicht ist für einige Dinge verantwortlich, die von der Speicher-Engine-Schicht verarbeitet werden.Habe mich darum gekümmert.
Wenn die Pushdown-Optimierung ohne Indexbedingungen verwendet wird, ruft die Speicher-Engine die Daten über den Index ab und gibt sie dann an MySQL Server zurück.MySQL-Server Urteilen Sie über die Filterbedingungen.
Wenn bei Verwendung der Indexbedingungs-Pushdown-Optimierung bestimmte Beurteilungsbedingungen für indizierte Spalten vorliegen, überträgt MySQL Server diesen Teil der Beurteilungsbedingungen an die Speicher-Engine, und die Speicher-Engine beurteilt dann, ob der Index die übergebenen Bedingungen erfüllt Nur wenn der Index die Bedingungen erfüllt, werden die Daten abgerufen und an den MySQL-Server zurückgegeben.
Durch die Optimierung des Indexbedingungs-Pushdowns kann die Anzahl der Abfragen der zugrunde liegenden Tabelle durch die Speicher-Engine verringert werden MySQL Die Häufigkeit, mit der der Server Daten von der Speicher-Engine empfangen hat.
select * from t_user where age > 20 and reward = 100000;
Erstellen Sie einen gemeinsamen Index (abc), (acb), (ab), (ac), nur einen Can-Index
Erstellen Sie gemeinsame Indizes (cab), (cba), (ca), (cb), nur c kann indizieren
Erstellen Sie (ba) einen gemeinsamen Index. Sowohl b als auch a können indiziert werden
Erstellen Sie einen gemeinsamen Index (bc). Sowohl b als auch c können indiziert werden
erstellen(bac) Gewerkschaftsindex, b und a können beide indiziert werden, sind aber langsamer als (ba) Der gemeinsame Index hat noch einen weiteren Vorteil: Das C-Feld kannIndex-Pushdown, reduziert die Anzahl der Tabellenrückgaben;
erstellen(bca) Gewerkschaftsindex, sowohl b als auch c können indiziert werden, aber es hat einen weiteren Vorteil gegenüber dem (bc) gemeinsamen Index, den das a-Feld kannIndex-Pushdown, reduziert die Anzahl der Tabellenrückgaben;
select * from tbn where a=? and b in (?,?) and c>?
Wird es indiziert?Diese Abfrage verwendet den gemeinsamen Index (A,B,C)
, da die Bedingung auf der Indexspalte basiert A
、B
、C
Die Bestellung kommt, was das ideale Nutzungsszenario darstellt.
für A=?
: Diese Bedingung ist eine exakte Übereinstimmung. MySQL verwendet den Index, um die Bedingung zu finden, die die Bedingung erfüllt. A=?
Aufnahme von.
für B IN (?, ?)
: Diese Bedingung gibt an B
Die Spalte kann zwei mögliche Werte annehmen. MySQL verwendet den Index, um alle Übereinstimmungen zu findenA=?
UndB
Die Spalte ist ein Datensatz mit einem dieser beiden Werte.
für C>?
: Diese Bedingung ist eine Bereichsabfrage.basiert bereits aufA
UndB
Basierend auf dem Filter verwendet MySQL weiterhin den Index zum SuchenC
Datensätze mit Spaltenwerten, die größer als der angegebene Wert sind.
Ich findeGründen bcda in OrdnungGewerkschaftsindexBesserZu diesem Zeitpunkt können sowohl das b- als auch das c-Feld indiziert werdend kann die Indexreihenfolge verwenden, um eine Dateisortierung zu vermeiden (zusätzliche Sortierung).Obwohl das letzte a-Feld nicht indiziert werden kann (a ist nicht in der richtigen Reihenfolge), kann es mithilfe des Index nach unten verschoben werden, um die Anzahl der Tabellenrückgaben zu verringern.
Die Reihenfolge des gemeinsamen Index ist zuerst der Name und dann das Alter. Strukturell wird zuerst nach Name und dann nach Alter sortiert, wenn die Namen gleich sind.Daher muss der Optimierer zu diesem Zeitpunkt zuerst den Namen abgleichen, und es tritt kein Indexfehler auf, sodass diese SQL die gemeinsame Indizierung verwenden kann.
Insbesondere kann nur der Name indiziert werdenNach der Namens-Rechts-Fuzzy-Abfrage sind die Werte des Altersfelds nicht in Ordnung, sodass das Alter nicht indiziert werden kann, das Alter jedoch indiziert werden kann.Index-Pushdown。
Die zuletzt abgefragten Felder sind „id“ und „name“. Diese beiden Felder befinden sich im gemeinsamen Index, sodass keine Notwendigkeit besteht, die Tabelle zurückzugeben. Es handelt sich um eine Indexabdeckungsabfrage.
Die Namens-Rechts-Fuzzy-Abfrage ist eine Bereichsabfrage und die folgenden Felder können nicht indiziert werden