Как я могу получить план выполнения для представления?


9

У меня есть схема с рядом просмотров. Мне нужно проверить планы выполнения, чтобы убедиться, что соответствующие индексы на месте и используются.

Как мне это сделать?

Я предпочел бы не нужно копировать и вставлять его из show create view <viewname>INTO explain, особенно некоторые мнения построены на вершине других взглядов , и это будет довольно боль.


1
Обратите внимание, что план выполнения может отличаться, когда VIEW используется в реальных запросах, поскольку он зависит от WHERE и других предложений в запросе, выбираемых из VIEW. Хотя MySQL довольно плохо умеет оптимизировать VIEW, у него есть некоторые оптимизации, например, когда условия понижаются.
Яннес

@ Джаннес, хорошая мысль, я не учел этот аспект. Безопасно ли предполагать, что план выполнения select * from <view_name>будет совпадать?
Мэтт Фенвик

1
Да, насколько я знаю. Если вы хотите, чтобы mysql использовал индекс для field1 в select * from <view-name>, где field1 = 10, тогда вы должны сделать представление действительно простым. Нет GROUP BY или UNION, например. Я думаю, вы могли бы сказать, что план выполнения, который вы просматриваете, является своего рода худшей ситуацией, в которой он мог бы только улучшиться, если бы mysql нашел оптимизацию для использования.
Янн

Ответы:


7

Это то, что я впервые попробовал:

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       |       |
+---------+------------+------+-----+---------+-------+

Очевидно, это не работает - это то же самое, что и делать describe view_name.

Тем не менее, select * from view_nameпохоже, работает:

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 за более простой ответ. Я скорректировал свой ответ на основе вашего. Вы должны принять свой ответ на этот.
RolandoMySQLDBA

7

Используйте таблицу information_schema.views

Это сгенерирует EXPLAIN для всех видов

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

Это сгенерирует EXPLAIN для всех представлений в базе данных mydb.

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

Попробуйте!

ОБНОВЛЕНИЕ 2012-03-22 11:30 ПО ВОСТОЧНОМУ ВРЕМЕНИ

@ MattFenwick, ваш ответ намного проще, чем мой. Вот пример, который я опробовал на своем компьютере под управлением MySQL 5.5.12. Я запустил EXPLAIN для версии SELECT из вашего ответа и для EXPLAIN, сгенерированной из моего ответа:

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>

Они оба разработали один и тот же план EXPLAIN. Я изменю свой ответ, чтобы реализовать ваш путь. Вы получаете +1 от меня, хотя это +2 для простоты. Вы должны пойти дальше и принять свой собственный ответ на этот.

Вот интересный факт о представлениях в MySQL: представление представлено в двух местах в базе данных information_schema

Это сгенерирует EXPLAIN для всех видов

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

или

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

Это сгенерирует EXPLAIN для всех представлений в базе данных mydb.

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

или

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 за показ того, что план выполнения одинаков в обоих направлениях!
Мэтт Фенвик
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.