Wie erhalte ich den Ausführungsplan für eine Ansicht?


9

Ich habe ein Schema mit mehreren Ansichten. Ich muss die Ausführungspläne überprüfen, um sicherzustellen, dass die entsprechenden Indizes vorhanden sind und verwendet werden.

Wie mache ich das?

Ich würde lieber nicht kopieren und die Ausgabe von Paste show create view <viewname>in explain, zumal einige der Ansichten auf anderen Ansichten gebaut werden und dies wäre durchaus ein Schmerz sein.


1
Beachten Sie, dass der Ausführungsplan unterschiedlich sein kann, wenn die ANSICHT in realen Abfragen verwendet wird, da dies von WHERE und anderen Klauseln in der Abfrage abhängt, die aus der ANSICHT ausgewählt werden. Obwohl MySQL bei der Optimierung von VIEWs ziemlich schlecht ist, gibt es einige Optimierungen, bei denen beispielsweise die Bedingungen herabgesetzt werden.
Jannes

@Jannes guter Punkt, ich habe diesen Aspekt nicht berücksichtigt. Ist es sicher anzunehmen, dass der Ausführungsplan von select * from <view_name>übereinstimmt?
Matt Fenwick

1
Ja soweit ich weiß. Wenn Sie möchten, dass MySQL einen Index für Feld1 in select * von <Ansichtsname> verwendet, wobei Feld1 = 10 ist, müssen Sie die Ansicht wirklich einfach halten. Zum Beispiel keine GROUP BY oder UNION. Ich denke, Sie könnten sagen, dass der Ausführungsplan, den Sie sich ansehen, die schlimmste Situation ist, da er nur dann besser werden kann, wenn mysql eine zu verwendende Optimierung findet.
Jannes

Antworten:


7

Das habe ich zuerst versucht:

mysql> explain view_name;
+---------+------------+------+-----+---------+-------+
| Field   | Type       | Null | Key | Default | Extra |
+---------+------------+------+-----+---------+-------+
| field1  | varchar(3) | YES  |     | NULL    |       |
| field2  | varchar(3) | YES  |     | NULL    |       |
| field3  | bigint(21) | NO   |     | 0       |       |
| field4  | bigint(21) | NO   |     | 0       |       |
+---------+------------+------+-----+---------+-------+

Offensichtlich funktioniert das nicht - es ist das gleiche wie zu tun describe view_name.

Scheint select * from view_namejedoch zu funktionieren:

mysql> explain select * from view_name;
+----+-------------+------------+------+---------------+------+---------+------+------+---------------------------------+
| id | select_type | table      | type | possible_keys | key  | key_len | ref  | rows | Extra                           |
+----+-------------+------------+------+---------------+------+---------+------+------+---------------------------------+
|  1 | PRIMARY     | <derived5> | ALL  | NULL          | NULL | NULL    | NULL |   18 |                                 |
|  1 | PRIMARY     | <derived3> | ALL  | NULL          | NULL | NULL    | NULL |  105 | Using where; Using join buffer  |
|  5 | DERIVED     | <derived6> | ALL  | NULL          | NULL | NULL    | NULL |   68 | Using temporary; Using filesort |
|  6 | DERIVED     | basetable  | ALL  | NULL          | NULL | NULL    | NULL |  928 | Using temporary; Using filesort |
|  3 | DERIVED     | <derived4> | ALL  | NULL          | NULL | NULL    | NULL |  386 | Using temporary; Using filesort |
|  4 | DERIVED     | basetable  | ALL  | NULL          | NULL | NULL    | NULL |  928 | Using temporary; Using filesort |
+----+-------------+------------+------+---------------+------+---------+------+------+---------------------------------+

+1 für eine klarere und einfachere Antwort. Ich habe meine Antwort basierend auf Ihrer angepasst. Sie sollten Ihre Antwort auf diese Frage akzeptieren.
RolandoMySQLDBA

7

Verwenden Sie die Tabelle information_schema.views

Dadurch wird die EXPLAIN für alle Ansichten generiert

mysql -uroot -p -AN -e"select concat('explain ',view_definition) from information_schema.views" > /root/ExplainViews.sql

Dadurch wird EXPLAIN für alle Ansichten in der mydb-Datenbank generiert

mysql -uroot -p -AN -e"select concat('explain ',view_definition) from information_schema.views where table_schema = 'mydb'" > /root/ExplainViews.sql

Versuche es !!!

UPDATE 2012-03-22 11:30 EDT

@ MattFenwick, deine Antwort ist viel einfacher als meine. Hier ist ein Beispiel, das ich auf meinem PC mit MySQL 5.5.12 ausprobiert habe. Ich habe EXPLAIN sowohl für die SELECT-Version aus Ihrer Antwort als auch für die EXPLAIN-Version ausgeführt, die aus meiner Antwort generiert wurde:

mysql> explain select * from bigjoin;
+----+-------------+-------+--------+---------------+---------+---------+---------------+------+-------------+
| id | select_type | table | type   | possible_keys | key     | key_len | ref           | rows | Extra       |
+----+-------------+-------+--------+---------------+---------+---------+---------------+------+-------------+
|  1 | SIMPLE      | k     | index  | NULL          | PRIMARY | 4       | NULL          |   14 | Using index |
|  1 | SIMPLE      | a     | eq_ref | PRIMARY       | PRIMARY | 4       | test.k.id_key |    1 | Using index |
|  1 | SIMPLE      | b     | ALL    | NULL          | NULL    | NULL    | NULL          |    4 |             |
+----+-------------+-------+--------+---------------+---------+---------+---------------+------+-------------+
3 rows in set (0.00 sec)

mysql> explain select `a`.`id_key` AS `id_key1`,`b`.`id_key` AS `id_key2` from ((`test`.`idlist` `k` left join `test`.`id_key_table` `a` on((`k`.`id_key` = `a`.`id_key`))) left join `test`.`new_keys_to_load` `b` on((`k`.`id_key` = `b`.`id_key`)));
+----+-------------+-------+--------+---------------+---------+---------+---------------+------+-------------+
| id | select_type | table | type   | possible_keys | key     | key_len | ref           | rows | Extra       |
+----+-------------+-------+--------+---------------+---------+---------+---------------+------+-------------+
|  1 | SIMPLE      | k     | index  | NULL          | PRIMARY | 4       | NULL          |   14 | Using index |
|  1 | SIMPLE      | a     | eq_ref | PRIMARY       | PRIMARY | 4       | test.k.id_key |    1 | Using index |
|  1 | SIMPLE      | b     | ALL    | NULL          | NULL    | NULL    | NULL          |    4 |             |
+----+-------------+-------+--------+---------------+---------+---------+---------------+------+-------------+
3 rows in set (0.00 sec)

mysql>

Beide haben den gleichen EXPLAIN-Plan erstellt. Ich werde meine Antwort ändern, um Ihren Weg umzusetzen. Du bekommst eine +1 von mir, obwohl es der Einfachheit halber +2 ist. Sie sollten fortfahren und Ihre eigene Antwort auf diese Frage akzeptieren.

Hier ist ein interessantes Faktoid zu VIEWs in MySQL: Eine Ansicht wird an zwei Stellen in der Datenbank information_schema dargestellt

Dadurch wird die EXPLAIN für alle Ansichten generiert

mysql -uroot -p -AN -e"select concat('explain select * from ',table_schema,'.',table_name,';') from information_schema.tables WHERE engine IS NULL" > /root/ExplainViews.sql

oder

mysql -uroot -p -AN -e"select concat('explain select * from ',table_schema,'.',table_name,';') from information_schema.views" > /root/ExplainViews.sql

Dadurch wird EXPLAIN für alle Ansichten in der mydb-Datenbank generiert

mysql -uroot -p -AN -e"select concat('explain select * from ',table_schema,'.',table_name,';') from information_schema.tables WHERE table_schema='mydb' AND engine IS NULL;" > /root/ExplainViews.sql

oder

mysql -uroot -p -AN -e"select concat('explain select * from ',table_schema,'.',table_name,';') from information_schema.views WHERE table_schema='mydb';" > /root/ExplainViews.sql

+1 für den Nachweis, dass der Ausführungsplan in beide Richtungen gleich ist!
Matt Fenwick
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.