ビューの実行プランを取得するにはどうすればよいですか?


9

いくつかのビューを持つスキーマがあります。実行プランをチェックして、適切なインデックスが配置され、使用されていることを確認する必要があります。

どうすればよいですか?

私はむしろからの出力をコピー&ペーストする必要はないだろうshow create view <viewname>explain景色の一部が他のビューの上に構築されている、特にとして、これは非常に苦痛になります。


1
VIEWを実際のクエリで使用する場合、VIEWから選択するクエリのWHEREおよび他の句に依存するため、実行プランは異なる場合があることに注意してください。MySQLはVIEWの最適化がかなり得意ではありませんが、たとえば条件がプッシュダウンされるようないくつかの最適化があります。
Jannes

@Jannes良い点、私はその側面を考慮していませんでした。の実行計画select * from <view_name>が一致すると想定しても安全ですか?
Matt Fenwick

1
ええ、私の知る限り。mysql でselect1のfield1 = 10のselect * fromでfield1のインデックスを使用する場合は、ビューを本当にシンプルに保つ必要があります。たとえば、GROUP BYやUNIONはありません。あなたが見ている実行プランは、mysqlが使用する最適化を見つけた場合にのみ良くなるという点で、最悪のケースの状況であると言えるでしょう。
Jannes、2012年

回答:


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

試してみる !!!

UPDATE 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計画を作成しました。私はあなたの方法を実装するために私の答えを変更します。簡単にするために+2ですが、私から+1を受け取ります。あなたは先に進んで、これに関するあなた自身の答えを受け入れるべきです。

MySQLのビューに関する興味深いfactoidは次のとおりです。ビューは、information_schemaデータベースの2つの場所で表されます

これにより、すべてのビューの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は、実行計画が双方向で同じであることを示します。
Matt Fenwick、2012年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.