如何获得视图的执行计划?


9

我有一个带有多个视图的架构。我需要检查执行计划,以确保适当的索引到位并正在使用。

我该怎么做呢?

我宁愿不必复制输出并将其粘贴show create view <viewname>到中explain,尤其是因为某些视图是建立在其他视图之上的,这会很痛苦。


1
请注意,在实际查询中使用VIEW时,执行计划可能会有所不同,因为它取决于WHERE和查询中从VIEW选择的其他子句。尽管MySQL在优化VIEW方面相当不利,但是它确实进行了一些优化,例如在降低条件的情况下。
Jannes 2012年

@Jannes好点,我没有考虑到这方面。是否可以安全地假设执行计划select * from <view_name>会匹配?
马特·芬威克

1
是的,据我所知。如果希望mysql在select * from <view-name>其中field1 = 10的情况下在field1上使用索引,则必须保持视图非常简单。例如,没有GROUP BY或UNION。我猜您可以说您正在查看的执行计划是最坏的情况,因为只有在mysql找到要使用的优化时它才能变得更好。
Jannes 2012年

Answers:


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 2012年

7

使用information_schema.views

这将为所有视图生成EXPLAIN

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

这将为mydb数据库中的所有视图生成EXPLAIN

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 EDT

@MattFenwick,您的答案比我的要简单得多。这是我在运行MySQL 5.5.12的PC上试用的示例。我在您的答案的SELECT版本和我的答案生成的EXPLAIN上都运行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中的VIEW的有趣事实:一个视图在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

这将为mydb数据库中的所有视图生成EXPLAIN

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表示执行计划是相同的!
马特·芬威克
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.