2017-08-17 1 views
0

Ich habe eine MariaDB-Datenbank, die ich zu optimieren versuche. Die aktuelle Tabelle hat 132 Millionen Zeilen und es ist schwierig, damit zu arbeiten.Kann es einen doppelten Index in einer MySQL-Datenbank geben

Untersuchen, warum INSERT auf meinem Tisch (InnoDB) so langsam sind, bemerke ich, was wie Duplikate INDEX aussieht. Hier ist die Ausgabe von SHOW INDEX:

Table U Key_name S_ Column_nam Co Cardina  Sub_pa Packed Nu Index_type Comment  Index_comment 
Twit 0 PRIMARY  1 ID_num  A 123302998 NULL NULL  BTREE  
Twit 1 User_ID  1 User_ID  A 408288  NULL NULL  BTREE  
Twit 1 Date_cr  1 Date_cr  A 123302998 NULL NULL  BTREE  
Twit 1 User_ID_2 1 User_ID  A 515912  NULL NULL  BTREE  
Twit 1 index_Orig 1 Original A 61651499 NULL NULL YES BTREE 

Ich verstehe nicht, warum die beiden INDEX auf User_ID unterschiedliche Mächtigkeit haben. Würde es einen Weg geben, einen von ihnen sicher zu entfernen, um INSERT-Abfragen zu beschleunigen?

Danke.

Antwort

0

Verwandte: Can cardinality differ for duplicate indexes in mysql?

Mir scheinen, dass Sie das mit der am wenigsten richtigen Mächtigkeit löschen sollten.

+0

Gut verwandtes Thema in der Tat. Mein zweites Problem ist, dass die Kardinalität des User_ID Index zwischen 40.000 und 50.000 liegen sollte.Ich glaube nicht, dass ich irgendeiner dieser Zahlen vertrauen kann. – ylnor

+0

@ylnor hast du versucht, Tabelle zu optimieren und zu analysieren? Für die Berechnung Ihrer Kardinalität können Sie den eindeutigen – Noob

+0

Dank, ich lief gerade Optimieren, sollte eine Weile dauern, werde ich meine Frage danach aktualisieren. – ylnor

0

Die meisten InnoDB-Statistiken basieren auf ungefähren Stichproben, so dass sie ziemlich variabel und ungenau sein können, aber dennoch gut genug sind, um den Abfrageoptimierer zu führen.

Die Ausführung von ANALYZE TABLE wird basierend auf einer neuen zufällig ausgewählten Gruppe von Seiten neu berechnet, und dann sehen Sie möglicherweise, dass sich die Schätzungen ändern. Dies dauert nicht lange, und dies für einen großen Tisch zu tun dauert nicht länger als für einen kleinen Tisch.

Um Ihre ursprüngliche Frage zu beantworten, ja, können Sie definitiv doppelte Indizes, d. H. Mehr als einen Index für die exakt gleichen Spalten. MySQL verhindert das nicht. Es vertraut darauf, dass Sie verantwortlich sind und Sie wissen, was Sie tun.

Sie können einen beliebigen Index löschen. Das Löschen eines Index ist eine schnelle Operation und erstellt die Tabelle nicht neu (es sei denn, Sie verwenden eine sehr alte Version von MySQL). Für Details lesen Sie https://dev.mysql.com/doc/refman/5.5/en/innodb-create-index.html und seine Unterabschnitte.

OPTIMIZE TABLE sollte nicht notwendig sein. Es erstellt die Tabelle neu erstellen, einschließlich aller Daten und aller Indizes. Es braucht viel Zeit. Aber sobald es fertig ist, wird es auch eine erneute Stichprobenanalyse von Indexstatistiken geben, genau wie ANALYZE TABLE.

Aber ich würde nicht erwarten, dass eine große Leistungsänderung einen von Ihren vier sekundären Indizes fallen lässt (ich zähle nicht die Möglichkeit, Ihren PRIMARY-Index fallen zu lassen, da dies der gruppierte Index ist, der die Tabelle selbst ist) .

Sie können auch gerne lesen https://dev.mysql.com/doc/refman/5.6/en/insert-optimization.html und https://dev.mysql.com/doc/refman/5.6/en/optimizing-innodb-bulk-data-loading.html

0

(Kommentare, ist eine eher zufällige Reihenfolge.)

  • Cardinality Werte basieren auf „Zufallssprüngen“ in den Index, und damit sind ungefähr. Sie können auf jeden Fall um den Faktor 2 abweichen.

  • Es gibt (noch) kein "Histogramm", das Hinweise auf eine ungleichmäßige Verteilung gibt.

  • Sie haben einen doppelten Index. Sie können entweder eins von ihnen sicher fallen lassen. Dies spart Speicherplatz und beschleunigt die Verarbeitung des Änderungspuffers ein wenig.

  • Ich sehe keine 'zusammengesetzten' Indizes. Abhängig von den Abfragen, die Sie haben, können sie sehr wichtig sein.

  • Ein INSERT in eine InnoDB-Tabelle muss zuerst alle UNIQUE Schlüssel für die einzufügende Zeile prüfen, die ein Duplikat ist. Der PK ist der einzige UNIQUE Schlüssel in dieser Tabelle. Die sekundären Index-Updates werden über den "Change Buffer" verzögert.

  • Schließlich müssen die sekundären Indizes aktualisiert werden. Vielleicht Dies ist, wo Sie jetzt sind. Wie viele Einsätze pro Sekunde führst du aus? Sind sie "dosiert"? Ist jede Zeile in einer separaten Transaktion (z. B. über autocommit=ON)? (Mehr dazu, wenn Sie antworten.)

  • Wie viel RAM? Wie ist die Einstellung innodb_buffer_pool_size? Diese Faktoren sind für die gesamte Diskussion von entscheidender Bedeutung.

  • Wie ist die Einstellung innodb_flush_log_at_trx_commit? Dies steuert einen zusätzlichen Festplattentreffer bei jeder Transaktion.

  • Das Löschen der PRIMARY KEY ist normalerweise nicht etwas zu tun. Und ich bin mir ziemlich sicher, dass es eine teure Rekonstruktion der Tabelle in jeder Version erzwingt.

  • OPTIMIZE TABLE ist fast nie nützlich für InnoDB. Ja, es macht etwas Defragmentierung. Aber Sie werden die Tabelle schnell wieder erweitern.

  • Ist ID_numAUTO_INCREMENT? Wenn dies der Fall ist, ist die Einfügung in die Daten (und PK) ziemlich billig, da sie in das "Ende" der Tabelle schreibt.

  • Wenn einige/alle Sekundärindizes verstreut sind, kann es passieren, dass die Lese-, Änderungs- und Schreiboperation zum Aktualisieren des Index viel Zeit in Anspruch nimmt und dadurch das System verlangsamt. Es würde Ihre Einfügungen nur dadurch verlangsamen, dass der Änderungspuffer stattfinden muss, um Platz für virtuelle Aktualisierungen zu schaffen.

0

Doppelte Index Auswirkungen auf die Datenbank-Performance hat, sollten Sie besser drop index verwenden, es zu beheben:

mysql> alter table your_table_name drop index key_name_of_duplicate_index; 

Zum Beispiel in Ihrem Fall:

mysql> alter table Twit drop index User_ID_2; 

Sie wollen könnte verstehe, wie der doppelte Index kommt. Hier ist ein Beispielfall den doppelten Index zu importieren:

mysql> alter table Twit add index User_ID; 
mysql> alter table Twit add index User_ID; 

Führen Sie diesen Befehl add index zweimal doppelten Index verursachen (könnte in verschiedener Zeit laufen, weil jemand vergessen, dass es wurde bereits hinzugefügt). Die beste Praxis add index auszuführen ist immer key_name verwendet doppelten Index zu vermeiden:

mysql> alter table Twit add index User_ID(User_ID); 
mysql> alter table Twit add index User_ID(User_ID); 

Dann wird der zweite Befehl fehl.

Verwandte Themen