IndexmodellHash-Tabelle
Geordnetes Array: Die Leistung sowohl bei Abfragen mit gleichen Werten als auch bei Bereichsabfragen ist ausgezeichnet, das Einfügen und Löschen von Daten erfordert jedoch eine Datenverschiebung, die zu kostspielig ist. Daher gilt es nur für statische Speicher-Engines. Binär ausgeglichener Baum: Das linke Kind jedes Knotens ist kleiner als der übergeordnete Knoten und der übergeordnete Knoten ist kleiner als das rechte Kind. Die zeitliche Komplexität beträgt O(log(N)) Ausgeglichener Baum mit mehreren Zweigen: Der Index wird nicht nur im Speicher gespeichert, sondern auch auf die Festplatte geschrieben. Um die Festplattenlesevorgänge für eine Abfrage zu minimieren, muss der Abfrageprozess auf so wenig Datenblöcke wie möglich zugreifen. Daher wird ein „N-ärer“ Baum verwendet. B+BaumB-Baum und B+Baum B-Baum B+Baum InnoDB verwendet das B+-Baumindexmodell. Angenommen, wir haben eine Tabelle mit einer Primärschlüsselspalte „ID“, einem Feld „k“ in der Tabelle und einem Index für „k“, wie unten dargestellt:
Vorsichtsmaßnahmen
// Nehmen wir eine Datenseite von 16 KB, eine Datenzeile von 1 KB, einen Indexzeiger von 6 Bytes und ein Indexfeld vom Typ Bigint (8 Bytes) an. // Anzahl der Indizes K = 16*1024/(8+6) = 1170 // Anzahl der Datensätze in einem einzelnen Blattknoten N = 16/1 = 16 // Schicht 3 B+ Datensatznummer V = K*K*N = 21902400 MyISAM verwendet ebenfalls B+Tree-Indizes. Der Unterschied besteht darin, dass es nicht zwischen Primärschlüssel- und Nicht-Primärschlüssel-Indizes unterscheidet. Beide sind nicht gruppierte Indizes. Die Blattknoten speichern Zeiger auf Datendateien. IndexauswahlDer Zweck des Optimierers, der einen Index auswählt, besteht darin, einen optimalen Ausführungsplan zu finden und die Anweisung zu den niedrigsten Kosten auszuführen. In der Datenbank ist die Anzahl der gescannten Zeilen einer der Faktoren, die die Ausführungskosten beeinflussen. Weniger gescannte Zeilen bedeuten weniger Festplattenzugriffe und eine geringere CPU-Auslastung. Natürlich ist die Anzahl der gescannten Zeilen nicht das einzige Beurteilungskriterium. Der Optimierer trifft auch eine umfassende Beurteilung basierend auf Faktoren wie der Verwendung temporärer Tabellen und der Sortierung. So berechnen Sie die Anzahl der Scanzeilen Je mehr unterschiedliche Werte ein Index hat, desto diskriminativer ist der Index. Die Anzahl der unterschiedlichen Werte in einem Index wird als Kardinalität bezeichnet. -- Zeigen Sie die aktuelle Indexbasis an mysql> show index from test; +-------+------------+----------+--------------+--------------+--------------+--------------+-------------+----------+---------+---------+---------+---------+---------+---------+---------+ | Tabelle | Nicht_eindeutig | Schlüsselname | Sequenz_im_Index | Spaltenname | Sortierung | Kardinalität | Unterteil | Gepackt | Null | Indextyp | Kommentar | Indexkommentar | +-------+------------+----------+--------------+--------------+--------------+--------------+-------------+----------+---------+---------+---------+---------+---------+---------+---------+ | Test | 0 | PRIMARY | 1 | ID | A | 100256 | NULL | NULL | | BTREE | | | | Test | 1 | index_a | 1 | a | A | 98199 | NULL | NULL | JA | BTREE | | | +-------+------------+----------+--------------+--------------+--------------+--------------+-------------+----------+---------+---------+---------+---------+---------+---------+---------+ Aus Leistungssicht verwendet InnoDB Stichprobenstatistiken. Standardmäßig wählt es N Datenseiten aus, zählt die unterschiedlichen Werte auf diesen Seiten, ermittelt einen Durchschnittswert und multipliziert ihn dann mit der Anzahl der Seiten dieses Indexes, um die Kardinalität dieses Indexes zu erhalten. Daher weisen die beiden obigen Indizes nicht die gleiche Kardinalität auf. Die Datentabelle wird kontinuierlich aktualisiert und die Indexstatistiken bleiben nicht unverändert. Wenn daher die Anzahl der geänderten Datenzeilen 1/M überschreitet (der Standardwert ist 10, wenn innodb_stats_persistent=on ist, und andernfalls 16), wird automatisch eine Neuindizierung der Statistiken ausgelöst. mysql> Variablen wie „%innodb_stats_persistent%“ anzeigen; +--------------------------------------+-------------+ | Variablenname | Wert | +--------------------------------------+-------------+ -- Ob die Aktualisierung der Statistiken automatisch ausgelöst werden soll. Wenn die geänderten Daten 10 % überschreiten, werden die Statistiken neu berechnet | innodb_stats_auto_recalc | EIN | -- Steuert, ob zum Löschen markierte Datensätze bei der Neuberechnung von Statistiken berücksichtigt werden | innodb_stats_include_delete_marked | OFF | -- Statistische Methode für Nullwerte. Wenn die Variable auf nulls_equal gesetzt ist, werden alle NULL-Werte als gleich betrachtet | innodb_stats_method | nulls_equal | -- Ob die Aktualisierung der Statistiken beim Bearbeiten von Metadaten ausgelöst werden soll | innodb_stats_on_metadata | OFF | --Ob Statistiken dauerhaft gespeichert werden | innodb_stats_persistent | EIN | -- innodb_stats_persistent=on, Anzahl der Beispielseiten für die dauerhafte Statistikstichprobenerhebung | innodb_stats_persistent_sample_pages | 20 | -- Veraltet, ersetzt durch innodb_stats_transient_sample_pages | innodb_stats_sample_pages | 8 | -- Vorübergehende Beispielseitennummer | innodb_stats_transient_sample_pages | 8 | +--------------------------------------+-------------+
-- Indexinformationen neu berechnen mysql> analyze table t; Auswirkung der Sortierung auf die Indexauswahl -- Erstellen Sie eine Tabelle mysql> CREATE TABLE `t` ( `id` int(11) NICHT NULL, `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, Primärschlüssel (`id`), SCHLÜSSEL `a` (`a`), SCHLÜSSEL `b` (`b`) )ENGINE=InnoDB; - Definieren Sie das Testdatenspeicherverfahren mysql> Trennzeichen; PROZEDUR ERSTELLEN idata () BEGINNEN Erklären Sie, dass ich INT; Setze i = 1; WÄHREND (i <= 100000) TUN EINFÜGEN IN t WERTE (ich, ich, ich); Setze i = i + 1; ENDE WÄHREND ; ENDE; Trennzeichen ; -- Führen Sie die gespeicherte Prozedur aus und fügen Sie Testdaten ein mysql> CALL idata (); - Zeigen Sie den Ausführungsplan an, indem Sie den Index auf Feld a verwenden. mysql> erklären Sie „select * from t“, wobei a zwischen 10000 und 20000 liegt; +----+--------------+-------+-----------+---------------+-----+-----------+------+----------+-----------+---------------------------+ | ID | Auswahltyp | Tabelle | Typ | mögliche Schlüssel | Schlüssel | Schlüssellänge | Ref. | Zeilen | Extra | +----+--------------+-------+-----------+---------------+-----+-----------+------+----------+-----------+---------------------------+ | 1 | SIMPLE | t | Bereich | a | a | 5 | NULL | 10000 | Indexbedingung verwenden | +----+--------------+-------+-----------+---------------+-----+-----------+------+----------+-----------+---------------------------+ -- Da Feld b sortiert werden muss, wird es geordnet, obwohl Index b mehr Zeilen scannen muss. Unter Berücksichtigung der Anzahl der zu scannenden Zeilen und der Sortierung wählt der Optimierer Index b, da er glaubt, dass die Kosten geringer sind. mysql> erklärt select * from t where (a zwischen 1 und 1000) und (b zwischen 50000 und 100000) order by b limit 1; +----+--------------+-------+-----------+---------------+-----+------+------+------+------+------+------------------------------------+ | ID | Auswahltyp | Tabelle | Typ | mögliche Schlüssel | Schlüssel | Schlüssellänge | Ref. | Zeilen | Extra | +----+--------------+-------+-----------+---------------+-----+------+------+------+------+------+------------------------------------+ | 1 | SIMPLE | t | Bereich | a,b | b | 5 | NULL | 50128 | Indexbedingung verwenden; Where verwenden | +----+--------------+-------+-----------+---------------+-----+------+------+------+------+------+------------------------------------+ -- Lösung 1: Verwenden Sie „Force Index“, um Index a zu erzwingen und die falsche Auswahl des Optimierers zu korrigieren. Dies wird nicht empfohlen (nicht universell, und die Anweisung muss geändert werden, wenn der Indexname geändert wird). mysql> erklären Sie „select * from t force index(a), wobei (a zwischen 1 und 1000) und (b zwischen 50000 und 100000) sortieren nach b, Grenze 1; +----+-----------+----------+-----------+---------------+-----+------+------+------+----------------------------------------------------+ | ID | Auswahltyp | Tabelle | Typ | mögliche Schlüssel | Schlüssel | Schlüssellänge | Ref. | Zeilen | Extra | +----+-----------+----------+-----------+---------------+-----+------+------+------+----------------------------------------------------+ | 1 | SIMPLE | t | Bereich | a | a | 5 | NULL | 999 | Indexbedingung verwenden; Where verwenden; Filesort verwenden | +----+-----------+----------+-----------+---------------+-----+------+------+------+----------------------------------------------------+ -- Lösung 2: Weisen Sie MySQL an, den gewünschten Index zu verwenden und nach b, a zu sortieren. Der Optimierer muss die Kosten für die Sortierung von a berücksichtigen. mysql> erläutern Sie „select * from t“, wobei (a zwischen 1 und 1000) und (b zwischen 50000 und 100000) nach b, a, Limit 1 sortiert ist; +----+-----------+----------+-----------+---------------+-----+------+------+------+----------------------------------------------------+ | ID | Auswahltyp | Tabelle | Typ | mögliche Schlüssel | Schlüssel | Schlüssellänge | Ref. | Zeilen | Extra | +----+-----------+----------+-----------+---------------+-----+------+------+------+----------------------------------------------------+ | 1 | SIMPLE | t | Bereich | a,b | a | 5 | NULL | 999 | Indexbedingung verwenden; Where verwenden; Filesort verwenden | +----+-----------+----------+-----------+---------------+-----+------+------+------+----------------------------------------------------+ -- Lösung 3: In einigen Szenarien können wir einen geeigneteren Index erstellen, um ihn dem Optimierer zur Auswahl bereitzustellen, oder den falsch verwendeten Index löschen ALTER TABLE `t` DROP INDEX `a`, DROP INDEX `b`, INDEX HINZUFÜGEN `ab` (`a`,`b`); Indexoptimierung IndexselektivitätIndexselektivität = Kardinalität / Gesamtzahl der Zeilen - Selektiver Index des Felds xxx in Tabelle t: select count(distinct xxx)/count(id) from t; Unter der Selektivität eines Index versteht man das Verhältnis von eindeutigen Indexwerten (Kardinalität) zur Anzahl der Tabellendatensätze. Die Selektivität ist ein Indikator für die Screening-Fähigkeit des Index. Der Indexwertbereich liegt zwischen 0 und 1. Je höher die Selektivität, desto höher der Indexwert. Bei Verwendung einer normalen Indexabfrage wird zuerst der normale Index geladen, der Primärschlüssel der tatsächlichen Zeile wird über den normalen Index abgefragt und dann wird der Primärschlüssel verwendet, um die entsprechende Zeile über den gruppierten Index abzufragen, um so alle Zeilen in einer Schleife abzufragen. Wenn Sie den gesamten Clusterindex direkt durchsuchen, müssen Sie nicht zwischen dem normalen Index und dem Clusterindex hin- und herwechseln. Verglichen mit dem Gesamtaufwand der beiden Vorgänge ist das Durchsuchen der gesamten Tabelle möglicherweise effizienter. In der tatsächlichen Arbeit hängt es immer noch von der Geschäftssituation ab. Wenn die Datenverteilung ungleichmäßig ist, fragen die tatsächlichen Abfragebedingungen immer den Teil mit weniger Daten ab. Das Hinzufügen eines Index für die Spalte mit niedrigerer Indexauswahl kann ebenfalls einen guten Effekt haben. AbdeckungsindexDurch das Abdecken von Indizes kann die Anzahl der Baumsuchvorgänge verringert und die Abfrageleistung erheblich verbessert werden. Daher ist die Verwendung von Abdeckindizes eine gängige Methode zur Leistungsoptimierung. -- Sie müssen nur den Wert der ID überprüfen, und der Wert der ID befindet sich bereits im k-Indexbaum, sodass Sie das Abfrageergebnis direkt bereitstellen können, ohne zur Tabelle zurückkehren zu müssen. Wählen Sie ID aus T aus, wobei k zwischen 3 und 5 liegt. -- Feld V hinzufügen. V muss für jede Abfrage zurückgegeben werden. Sie können erwägen, k und v zu einem gemeinsamen Index zusammenzufassen. select ID,V from T, wobei k zwischen 3 und 5 liegt. Prinzip des ganz linken Präfixes + Index-Pushdown-- Erstellen Sie einen gemeinsamen Index für die drei Spalten „ID“, „Name“ und „Alter“. -- Erfüllen Sie das Prinzip des ganz linken Präfixes, und sowohl Name als auch Alter werden indiziert. Wählen Sie „* aus T“, wobei „Name“ = „xxx“ und „Alter“ = „12“ lautet. -- Mysql optimiert und passt die Reihenfolge von Name und Alter automatisch an. Sowohl Name als auch Alter werden indiziert. select * from T where age=12 and name='xxx' -- Wenn der Name das Prinzip des am weitesten links stehenden Präfixes erfüllt, wird der Index verwendet. MySQL 5.6 führt eine Pushdown-Optimierung für Indexbedingungen ein, d. h. die Datensätze, die age=12 nicht erfüllen, werden zuerst im Index herausgefiltert und dann an die Tabelle zurückgegeben. select * from T where name like 'xxx%' and age=12 -- Erfüllt nicht das Prinzip des ganz linken Präfixes, es wird kein Index verwendet. Wählen Sie * aus T aus, wobei der Name beispielsweise „%xxx%“ und das Alter 12 ist. -- Erfüllt das Prinzip des ganz linken Präfixes. Der Name verwendet den Index select * from T, wobei name='xxx' ist. -- Erfüllt nicht das Prinzip des ganz linken Präfixes und verwendet nicht den Index „select * from T where age=12“ Grundsätze für die Erstellung gemeinsamer Indizes:
Präfixindexmysql> Tabelle SUser erstellen( ID Bigint vorzeichenloser Primärschlüssel, Name varchar(64), E-Mail varchar(64), ... )Engine=innodb; -- Das folgende Abfrageszenariomysql> select name from SUser where email='xxx'; -- Lösung 1: Volltextindex. Die Anzahl der Tabellenrückgaben wird durch die Datenmenge bestimmt, die die Bedingungen erfüllt. mysql> alter table SUser add index index1(email); -- Lösung 2: Präfixindex. Die Anzahl der Tabellenrückgaben wird durch das Präfixübereinstimmungsergebnis bestimmt. mysql> alter table SUser add index index2(email(6)); Präfixindizes können Platz sparen, aber Sie müssen auf die Definition der Präfixlänge achten. Während Sie Platz sparen, sollten Sie die Abfragekosten nicht zu sehr erhöhen, d. h. die Anzahl der Überprüfungen der Tabellenrückgaben reduzieren. Wie stelle ich die entsprechende Präfixlänge ein? -- Stellen Sie ein akzeptables Unterscheidungsverlustverhältnis vor und wählen Sie die kleinste Präfixlänge, die die Bedingungen erfüllt. Wählen Sie count(distinct left(email,n))/count(distinct email) von SUser. Was passiert, wenn die entsprechende Präfixlänge länger ist? Wenn beispielsweise die ID-Kartennummer die Anforderungen zur Unterscheidung erfüllt, kann ein Präfixindex mit mehr als 12 Ziffern erforderlich sein. Der eingesparte Platz ist begrenzt und die Abfragekosten erhöhen sich. Daher ist die Verwendung eines Präfixindex nicht erforderlich. An diesem Punkt können wir den Einsatz der folgenden Methoden in Betracht ziehen: Rückwärtsspeicherung -- String-Umkehrabfrage während der Abfrage mysql> select field_list from t where id_card = reverse('input_id_card_string'); Verwenden von Hash-Feldern - Erstellen Sie ein Integer-Feld zum Speichern des ID-Karten-Verifizierungscodes und erstellen Sie einen Index für dieses Feld mysql> alter table t add id_card_crc int unsigned, add index(id_card_crc); -- Verwenden Sie das Hash-Feld, um nach Index zu suchen, und verwenden Sie dann die ursprüngliche Feldgenauigkeit, um MySQL zu filtern. Wählen Sie „field_list“ aus t aus, wobei id_card_crc=crc32('input_id_card_string') und id_card='input_id_card_string' Nachteile der beiden oben genannten Methoden:
Welchen Einfluss hat der Präfixindex auf den Überdeckungsindex? -- Wenn Sie einen Präfixindex verwenden, benötigen Sie keinen überdeckenden Index, um die Abfrageleistung zu optimieren. select id,email from SUser where email='xxx'; Eindeutiger IndexEs wird empfohlen, einen normalen Index zu verwenden. Der eindeutige Index kann den Änderungspuffer nicht verwenden und weist eine niedrige Speichertrefferrate auf. Indexfehler
ZusammenfassenDies ist das Ende dieses Artikels über MySQL-Indexauswahl und -Optimierung. Weitere relevante Inhalte zur MySQL-Indexauswahl und -Optimierung finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird! Das könnte Sie auch interessieren:
|
<<: Webdesign-TabIndex-Element
>>: Verwenden Sie Elasticsearch, um Indexdaten regelmäßig zu löschen
Dieser Artikel untersucht die ES6-for...of-Schlei...
Nachdem Sie den folgenden Artikel gelesen haben, ...
Im vorherigen Artikel https://www.jb51.net/articl...
Ich habe vorher einen Tag damit verbracht. Obwohl...
Einführung react-i18next ist ein leistungsstarkes...
Einführung Um Datenverlust in einer Produktionsum...
Inhaltsverzeichnis Die Bedeutung der Standard-Com...
In diesem Artikel sind einige sogenannte Spezifik...
Klicken Sie auf den Ankerlink, um reibungslos zu ...
In diesem Artikel wird jQuery verwendet, um den E...
Szenario: Wenn Seite A Seite B öffnet, muss Seite...
Wenn der Tabellenkopf fixiert ist, muss er in zwe...
Ich habe meinen Raspberry Pi-Server vor zwei Tage...
Datenbank-Benutzerinformationsdatenbetrieb für On...
Seitenverzeichnisstruktur Beachten Sie, dass Sie ...