Woher liest der MySQL Query Optimizer die Indexstatistik?


14

Ich versuche festzustellen, woher der MySQL-Optimierer die Liste der Indizes bezieht, die für eine Tabelle verfügbar sind, wenn er die Kosten für eine Abfrage schätzt (vorbereitet).


+1 für diese gute Frage, da Entwickler und Datenbankadministratoren pausieren und darüber nachdenken sollten, wie Indexstatistiken erstellt und gespeichert werden.
RolandoMySQLDBA

Als Referenz von MySQL Dokumentation Website: < dev.mysql.com/doc/refman/5.0/en/innodb-restrictions.html >> ANALYZE TABLEErmittelt Indexkardinalität (wie in der Cardinality Spalte der angezeigte SHOW INDEXAusgabe) von acht Zufallssprünge in jeden tun der Indexbäume und Aktualisieren der Indexkardinalitätsschätzungen entsprechend. Da es sich nur um Schätzungen handelt, können wiederholte Durchläufe von ANALYZE TABLE unterschiedliche Zahlen ergeben. Dies macht ANALYZE TABLEInnoDB-Tabellen schnell, ist jedoch nicht 100% genau, da nicht alle Zeilen berücksichtigt werden.
Chen Xie

Antworten:


6

Die direkte Antwort dafür wäre

informationsschema.statistik

mysql> desc information_schema.statistics;
+---------------+---------------+------+-----+---------+-------+
| Field         | Type          | Null | Key | Default | Extra |
+---------------+---------------+------+-----+---------+-------+
| TABLE_CATALOG | varchar(512)  | NO   |     |         |       |
| TABLE_SCHEMA  | varchar(64)   | NO   |     |         |       |
| TABLE_NAME    | varchar(64)   | NO   |     |         |       |
| NON_UNIQUE    | bigint(1)     | NO   |     | 0       |       |
| INDEX_SCHEMA  | varchar(64)   | NO   |     |         |       |
| INDEX_NAME    | varchar(64)   | NO   |     |         |       |
| SEQ_IN_INDEX  | bigint(2)     | NO   |     | 0       |       |
| COLUMN_NAME   | varchar(64)   | NO   |     |         |       |
| COLLATION     | varchar(1)    | YES  |     | NULL    |       |
| CARDINALITY   | bigint(21)    | YES  |     | NULL    |       |
| SUB_PART      | bigint(3)     | YES  |     | NULL    |       |
| PACKED        | varchar(10)   | YES  |     | NULL    |       |
| NULLABLE      | varchar(3)    | NO   |     |         |       |
| INDEX_TYPE    | varchar(16)   | NO   |     |         |       |
| COMMENT       | varchar(16)   | YES  |     | NULL    |       |
| INDEX_COMMENT | varchar(1024) | NO   |     |         |       |
+---------------+---------------+------+-----+---------+-------+
16 rows in set (0.01 sec)

Sie können aus dieser Tabelle mit AUSWÄHLEN

SELECT * FROM information_schema.statistics
WHERE table_schema='mydb' AND table_name='mytable';

oder sehen Sie sich die Statistiken an, indem Sie tun

SHOW INDEXES FROM mydb.mytable;

Bitte beachten Sie, dass diese Tabelle in einer schreiblastigen Umgebung nicht immer korrekt ist. In regelmäßigen Abständen müssen Sie ANALYZE TABLE für alle MyISAM-Tabellen ausführen , die häufig aktualisiert werden. Andernfalls kann der MySQL Query Optimizer, der sich auf information_schema.statistics stützt, bei der Entwicklung von EXPLAIN-Plänen für Abfragen manchmal falsche Entscheidungen treffen. Die Indexstatistik muss so aktuell wie möglich sein.

ANALYZE TABLE hat absolut keine Auswirkungen auf InnoDB-Tabellen. Alle Indexstatistiken für InnoDB werden bei Bedarf durch Eintauchen in die BTREE-Seiten berechnet. Wenn Sie SHOW INDEXES FROM für eine InnoDB-Tabelle ausführen, sind die angezeigten Kardinalitäten daher immer Näherungswerte.

UPDATE 2011-06-21 12:17 EDT

Lassen Sie mich zur Verdeutlichung von ANALYZE TABLE eine neue Formulierung verwenden. ANALYZE TABLE auf InnoDB-Tabellen auszuführen ist völlig nutzlos. Selbst wenn Sie ANALYZE TABLE für eine InnoDB-Tabelle ausgeführt haben, führt die InnoDB-Speicherengine immer wieder einen Sprung in den Index für Kardinalitätsannäherungen durch und verwirft so die gerade erstellten Statistiken . Tatsächlich führte Percona einige Tests an ANALYZE TABLE durch und kam zu diesem Schluss.


5

Betreff: ANALYZE TABLE hat ABSOLUT KEINE AUSWIRKUNGEN auf InnoDB-Tabellen.

Ich bin mir nicht sicher, ob diese Aussage wahr ist. Wir haben viel mit dem Lesen und Schreiben von Innodb-Tabellen zu tun und wenn der mysql-Optimierer die falsche Wahl trifft, zeigt die EXPLAIN-Ausgabe der Abfrage eine schlechte Strategie. und auch SHOW INDEXES aus einer Innodb-Tabelle zeigen so viel Varianz in ihren Kardinalitätswerten. Das Ausführen eines ANALYZE-Befehls für diese Innodb-Tabellen behebt den EXPLAIN-Plan und beseitigt auch das Varianzverhalten der Kardinalität. Ich weiß nicht, ob der ANALYZE-Tabellenbefehl für Innodb-Tabellen die ganze Zeit hilft oder nicht, aber in unserem Fall hat er in 99% der Fälle geholfen.

Wir haben die schlechte Wahl des MySQL-Optimierers vollständig beseitigt, indem wir "STRAIGHT_JOIN" in unsere Abfragen aufgenommen haben. Dieser mysql-Optimierer hat mich gezwungen, keine schlechten Entscheidungen zu treffen oder irgendwelche Entscheidungen zu treffen, sondern einfach die JOIN-Bedingung zu befolgen, die in der Abfrage so definiert wurde, wie sie ist.


Ich habe meine Antwort aktualisiert, um die Nutzlosigkeit von ANALYZE TABLE in InnoDB-Tabellen hervorzuheben.
RolandoMySQLDBA

Ich stimme Ihrer Antwort zu, als Sie die Varianz der Kardinalität erwähnten. Genau das habe ich gesagt, als ich Kardinalitätsannäherungen sagte.
RolandoMySQLDBA

Ich musste auch erwähnen, dass die Verwendung von Hinweisen in Abfragen nicht immer das Beste ist, wenn der MySQL Query Optimizer dazu neigt, sie zeitweise zu entfernen. Hier ist ein Link zu den internen Vorgängen
RolandoMySQLDBA

2

ANALYZE TABLE for MyISAM durchsucht die gesamte Tabelle und erstellt Statistiken neu, die in der .MYI-Datei gespeichert sind (glaube ich). Es wird selten benötigt.

ANALYZE TABLE für InnoDB macht etwas - es macht den erwähnten Tauchgang. Das Problem ist, dass es möglicherweise hilft, die Situation verschlimmert oder (höchstwahrscheinlich) keinen sichtbaren Unterschied macht (außer bei Kardinalitäten).

Neuere Versionen versprechen, die 8 nicht so zufälligen Sonden in (1) mehr zufällige Sonden zu ändern, (2) die "8" zu ändern (es gibt Vor- und Nachteile davon!) Und (3) über Neustarts hinweg zu speichern.

Fazit: InnoDB hat es immer noch nicht richtig verstanden. Analysieren Sie, wenn Sie Lust dazu haben, aber halten Sie nicht den Atem an.

Aktualisieren

Das Umformulieren von ... ANALYZE TABLEwirkt sich vorübergehend (möglicherweise vorteilhaft, möglicherweise nicht) auf die Optimierung von InnoDB-Tabellen aus.

"Neuere Version": Ab 5.6.6 (2012) und MariaDB 10.1 (2014) werden Statistiken viel besser gehandhabt und ANALYZEwerden jetzt (1) seltener und (2) dauerhafter benötigt.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.