Bagaimana cara mendapatkan rencana eksekusi untuk tampilan?

9

Saya punya skema dengan sejumlah tampilan. Saya perlu memeriksa rencana eksekusi untuk memastikan indeks yang sesuai sudah ada dan digunakan.

Bagaimana saya melakukan ini?

Saya lebih suka tidak perlu menyalin dan menempelkan output dari show create view <viewname>ke explain, terutama karena beberapa pandangan dibangun di atas pandangan lain dan ini akan sangat menyebalkan.

Matt Fenwick
sumber
1
Perhatikan bahwa rencana eksekusi mungkin berbeda ketika VIEW digunakan dalam kueri kehidupan nyata, karena tergantung pada WHERE dan klausa lain dalam kueri yang memilih dari VIEW. Meskipun MySQL cukup buruk dalam mengoptimalkan TAMPILAN, itu memang memiliki beberapa optimasi di mana kondisi ditekan misalnya.
Jannes
@ Jean titik bagus, saya tidak mempertimbangkan aspek itu. Apakah aman untuk menganggap bahwa rencana eksekusi dari select * from <view_name>akan cocok?
Matt Fenwick
1
Ya sejauh yang saya tahu. Jika Anda ingin mysql menggunakan indeks pada field1 di pilih * dari <view-name> di mana field1 = 10 maka Anda harus menjaga tampilan sangat sederhana. Tidak ada GROUP BY atau UNION misalnya. Saya kira Anda bisa mengatakan rencana eksekusi yang Anda lihat adalah semacam situasi terburuk karena hanya bisa lebih baik jika mysql menemukan pengoptimalan untuk digunakan.
Jannes

Jawaban:

7

Inilah yang pertama kali saya coba:

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

Jelas ini tidak berhasil - sama seperti melakukan describe view_name.

Namun, select * from view_nametampaknya berhasil:

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 |
+----+-------------+------------+------+---------------+------+---------+------+------+---------------------------------+
Matt Fenwick
sumber
+1 untuk jawaban yang jelas dan lebih sederhana. Saya menyesuaikan jawaban saya berdasarkan jawaban Anda. Anda harus menerima jawaban Anda untuk yang ini.
RolandoMySQLDBA
7

Gunakan tabel information_schema.views

Ini akan menghasilkan EXPLAIN untuk semua tampilan

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

Ini akan menghasilkan EXPLAIN untuk semua tampilan di database mydb

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

Cobalah !!!

UPDATE 2012-03-22 11:30 EDT

@ MattFenwick, jawaban Anda jauh lebih sederhana daripada saya. Berikut adalah contoh yang saya coba pada PC saya yang menjalankan MySQL 5.5.12. Saya menjalankan EXPLAIN pada versi SELECT dari jawaban Anda dan EXPLAIN yang dihasilkan dari jawaban saya:

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>

Mereka berdua menghasilkan rencana JELASKAN yang sama. Saya akan mengubah jawaban saya untuk menerapkan cara Anda. Anda mendapatkan +1 dari saya meskipun itu +2 untuk kesederhanaan. Anda harus melanjutkan dan menerima jawaban Anda sendiri untuk yang satu ini.

Berikut ini adalah fakta menarik tentang TAMPILAN di MySQL: Tampilan diwakili di dua tempat di database information_schema

Ini akan menghasilkan EXPLAIN untuk semua tampilan

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

atau

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

Ini akan menghasilkan EXPLAIN untuk semua tampilan di database 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

atau

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
RolandoMySQLDBA
sumber
+1 untuk menunjukkan bahwa rencana eksekusi keduanya sama-sama!
Matt Fenwick