In MySQL können Sie mehrere Indizes für eine Tabelle angeben, aber wenn die Anweisung ausgeführt wird, wird der zu verwendende Index vom Executor in MySQL bestimmt. Nach welchen Grundsätzen wählt der Testamentsvollstrecker einen Index aus und wird möglicherweise der falsche Index ausgewählt? Schauen wir uns ein Beispiel an: Erstellen Sie Tabelle Y, legen Sie zwei gemeinsame Indizes fest und erstellen Sie eine gespeicherte Prozedur zum Einfügen von Daten.
CREATE TABLE `Y` ( `id` int(11) NICHT NULL AUTO_INCREMENT, `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, Primärschlüssel (`id`), SCHLÜSSEL `a` (`a`), SCHLÜSSEL `b` (`b`) )ENGINE=InnoDB; Trennzeichen;; Prozedur idata() erstellen beginnen deklariere i int; setze i=1; während(i<=100000)mache in Y einfügen (`a`,`b`) Werte(i, i); setze i=i+1; Ende während; Ende;; Trennzeichen ; rufen Sie idata() auf; Sehen Sie sich die folgenden Transaktionen an:
Wenn „select * from Y where a between 10000 and 20000;“ nur in Sitzung B ausgeführt wird, wird zweifelsohne Index a ausgewählt. Wenn Sie jedoch Sitzung A und Sitzung B nacheinander installieren, werden Sie feststellen, dass die Indexauswahl wie folgt ist: Es zeigt sich, dass der Executor im Szenario der Sitzung B nicht den Index auswählte, in dem sich a befand, sondern einen vollständigen Tabellenscan basierend auf dem Primärschlüsselindex wählte. setze long_query_time=0; --Öffnen Sie das Protokoll für langsame Abfragen und setzen Sie den Schwellenwert auf 0. Im aufgezeichneten Protokoll können Sie feststellen, dass MySQL den Index, in dem sich a befindet, nicht ausgewählt hat und länger gebraucht hat. Aus dieser Perspektive ist der MySQL-Optimierer möglicherweise nicht immer in der Lage, den richtigen Index auszuwählen. Um den Grund für dieses Phänomen zu verstehen, müssen wir mit der Auswahllogik des Optimierers beginnen. Optimierer Der Zweck des Optimierers in MySQL besteht darin, einen optimalen Ausführungsplan zu finden, um die Anweisung mit den geringsten Kosten auszuführen. Bei der Indexauswahl berücksichtigt der Optimierer vor allem folgende Faktoren:
Bestimmen der Anzahl der Scanzeilen Berechnen der Kardinalität eines Indexes Vor der Ausführung einer Anweisung kann MySQL die Anzahl der gescannten Zeilen nicht genau berechnen, schätzt jedoch die Anzahl der Datensätze anhand mathematischer Statistiken. Diese Statistik wird als „Diskriminierung“ des Index bezeichnet. Je mehr unterschiedliche Werte der Index enthält, desto höher ist die Diskriminierung. Die Anzahl der unterschiedlichen Werte in einem Index wird als Kardinalität bezeichnet. Je größer die Kardinalität, desto besser ist die Unterscheidungsfähigkeit des Index. Die Kardinalität ist hier die Kardinalität des Index, aber die Kardinalität ist nicht ganz genau. MySQL verwendet tatsächlich Stichprobenstatistiken, um die Kardinalität zu ermitteln.
In MySQL gibt es zwei Möglichkeiten zum Speichern von Indizes, die durch Festlegen von innodb_stats_persistent umgeschaltet werden können:
Da sich die Daten in der Tabelle ständig ändern, werden automatisch Indexstatistiken ausgelöst, wenn der aktualisierte Wert 1/M überschreitet. Es ist jedoch zu beachten, dass der Kardinalitätswert nicht genau ist, da es sich um eine Stichprobenstatistik handelt . Fehler bei der Schätzung der Anzahl der Scanzeilen Wie wir zuvor gesehen haben, beträgt die geschätzte Zeilenanzahl für Führen Sie dann Noch merkwürdiger ist, dass die geschätzte Zeilenanzahl von 37116 zwar nicht sinnvoll ist, aber viel kleiner ist als die 100015 eines vollständigen Tabellenscans. Warum wählt der Optimierer trotzdem einen vollständigen Tabellenscan? Schauen wir uns zuerst die zweite Frage an. Der Grund für die Wahl von 100015 ist, dass bei Verwendung von Index a zusätzlich zum Scannen des Index a auch ein Zurückgehen zur Tabelle erforderlich ist. Der Optimierer muss auch die Abfragekosten für den Primärschlüsselindex berücksichtigen, daher wird ein vollständiger Tabellenscan gewählt. Schauen wir uns nun noch einmal die erste Frage an, warum nicht die richtige Zeilenanzahl erreicht wird. Dies hängt mit der Konsistenzansicht zusammen. Zunächst ist in Sitzung A die Konsistenzansicht aktiviert, wird aber nicht übermittelt. Nachdem die nachfolgende Sitzung die Y-Tabelle gelöscht hat, werden dieselben Daten neu erstellt. Zu diesem Zeitpunkt hat jede Datenzeile zwei Versionen. Die alte Version sind die Daten vor dem Löschen und die neue Version sind die als gelöscht markierten Daten. Es gibt also tatsächlich zwei Kopien der Daten am Index a. Dies führt zu einem Fehler bei der geschätzten Zeilenanzahl.
Lösung zur Auswahl des falschen Index Wenn die Zeilenanzahl falsch geschätzt wird, können Sie folgende Methode verwenden: Wenn die von EXPLAIN berechnete Zeilenanzahl erheblich von der geschätzten Zeilenanzahl abweicht, können Sie die Indexinformationen mithilfe der Analysetabelle neu berechnen. Verwenden Sie „Force Index“, um den zu verwendenden Index direkt anzugeben, ohne den Optimierer eine Entscheidung treffen zu lassen. Der Einsatz von Gewalt kann jedoch auch Probleme mit sich bringen:
Optimieren Sie SQL-Anweisungen und weisen Sie den Optimierer an, den richtigen Index zu verwenden Schauen wir uns ein ähnliches Beispiel an: Schauen wir uns zunächst diesen Satz an. SQL-Auswahl * von Y, wobei a zwischen 1 und 1000 und b zwischen 5000 und 100000, sortiert nach b, Limit 1; Bei der Ausführung dieses Satzes können Sie Index a oder Index b wählen. Wir wissen, dass jeder Index einem B+-Baum entspricht. Da hier die Schnittmenge von a und b erhalten wird, müssen bei Auswahl des Index a die Zeilen 1 bis 10001 durchlaufen werden. Um den Index b auszuwählen, müssen die Zeilen 50000 - 100001 durchlaufen werden. Theoretisch sollte a als Index gewählt werden, der Optimierer wählt jedoch b als Index. Der Grund, warum hier b als Index gewählt wird, liegt darin, dass der Optimierer die nachfolgende Aber von der tatsächlichen Ausführungszeit her hat Index a eine kürzere Ausführungszeit, sodass MySQL erneut den falschen Index gewählt hat. Wir können Damit soll sichergestellt werden, dass die logischen Ergebnisse der Ausführung konsistent sind. Wenn beispielsweise Grenzwert 1 verwendet wird, sind die Ergebnisse von Es gibt eine weitere Änderung Wählen Sie * aus (Wählen Sie * aus t, wobei (a zwischen 1 und 1000) und (b zwischen 50000 und 100000) Sortierung nach b-Limit 100) Alias-Limit 1; Jetzt können Sie sehen, dass der Optimierer einen geeigneten Index gewählt hat. Der Grund dafür ist, dass der Grenzwert 100 den Optimierer glauben lässt, dass die Kosten für die Verwendung von Index b höher sind, und daher Index a wählt. Tatsächlich wird der Grenzwert 100 verwendet, um den Optimierer zu einer Entscheidung zu veranlassen. Anpassen des Indexes Können Sie einen besseren und geeigneteren Index finden oder die Indexprinzipien verwenden, um einige unnötige Indizes zu löschen? Zusammenfassen Jetzt wissen wir, dass MySQL bei der Indexauswahl Fehler machen kann. Beim Auswählen von Indizes durch den Optimierer gelten drei Hauptprinzipien: die Anzahl der zu scannenden Zeilen, das Vorhandensein einer temporären Tabelle und die Sortierung. Die Anzahl der gescannten Zeilen hängt hauptsächlich von der Kardinalität ab, und die Kardinalitätsstatistiken werden durch statistische Stichproben ermittelt, sodass die geschätzte Zeilenanzahl ungenau sein kann. Wenn die Anzahl der gescannten Zeilen falsch ist, können Sie die Tabelleninformationen mit Oben sind die Gründe aufgeführt, warum MySQL den falschen Index ausgewählt hat, sowie die detaillierten Lösungen. Weitere Informationen zum MySQL-Index finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM! Das könnte Sie auch interessieren:
|
<<: Das WeChat-Applet realisiert eine Links-Rechts-Verknüpfung
>>: Detaillierte Erklärung der Stammverzeichniseinstellungen in nginx.conf
Inhaltsverzeichnis Vorwort Was sind dynamische Ei...
Inhaltsverzeichnis MySQL-Berechtigungskontrolle B...
SQL-Methode zum Berechnen der Zeitstempeldifferen...
Heute habe ich eine virtuelle Maschine für ein Ex...
Inhaltsverzeichnis 1. Einleitung 2. Umschalten 1....
1. Was ist Semantisierung? Erklärung zum Bing-Wör...
1. Einleitung Beim Filtern unbekannter oder teilw...
Dieser Artikel erläutert anhand eines konkreten B...
Einführung in Dockerfile Docker kann automatisch ...
Wenn wir Frontend-Entwicklung betreiben, werden w...
System: VMTOOLs-Download: Verknüpfung: https://pa...
Flash-Dateiformate: .FLV und .SWF Für das Flash-Vi...
1. Was ist ein Proxyserver? Proxyserver: Wenn der...
Derzeit verfügt Nginx über einen Reverse-Proxy fü...
Als Nächstes werde ich zwei Tabellen erstellen un...