
実行計画の見方
どのDBMSでも共通項目
- 操作対象のオブジェクト(MySQLなら「table」)
- オブジェクトに対する操作の種類(MySQLなら「type」)
- 操作対象となるレコード数(MySQLなら「row」)
EXPLAIN PLAN FORコマンドとは
実行時に、オプティマイザが立てたSQLの実行計画を観察するツールです。
「実行計画」について分からない方は、下記の記事をご参照下さい。
Oracle:EXPLAIN PLAN FORコマンドの使い方
1.PLAN_TABLEテーブルの作成(最初のみ)
まず、EXPLAIN PLANコマンドは、SQLの実行計画を「PLAN_TABLE」というテーブルに格納します。
なので、最初に「PLAN_TABLEテーブル」というテーブルを作成する必要があります。
なお、一度作成したら、以後は作成する必要はないです。
まずは、「%ORACLE_HOME%\rdbms\admin\utlxplan.sql」ファイルのSQLを該当のスキーマに対して実行します。
SQL実行後、「PLAN_TABLE」がスキーマ内に作成されています。
2.SQL実行計画を保存する。
下記の構文を実行します。
1 |
EXPLAIN PLAN FOR <SQL> |
ためしに実行してみます。
実行すると、上記のように表示されました。
3.PLAN_TABLEテーブルから、SQL実行計画を抽出します。
そのまま、「PLAN_TABLE」のデータを読み取るのは大変なので、下記のSQLを実行して、結果を整形しましょう。
1 2 3 4 5 6 7 |
SELECT LPAD(' ',2*LEVEL) || RTRIM(OPERATION) || ' ' || RTRIM(OPTIONS) || ' ' || RTRIM(OBJECT_NAME) AS EXECUTION_PLAN FROM PLAN_TABLE CONNECT BY PRIOR id = parent_id START WITH ID = 0 |
実行結果
この結果では、「USER_MASTER」テーブルに対して、フルテーブルスキャンでアクセスしていることがわかります。
MySQL
実行計画の基本的な読み方
- 入れ子の深い操作ほど先に実行される。(深いテーブルに先にアクセスが行われる。)
フルテーブルスキャン
1 |
EXPLAIN select * from テーブル名; |
typeに「ALL」と記述されていたらフルテーブルスキャンになります。インデックスが使われていない状態になります。
インデックススキャン
1 |
EXPLAIN SELECT * FROM テーブル名 WHERE xxx_id = 'XXX'; |
typeに「const」と記述されていたらインデックススキャンになります。インデックスが使われていて最速です。
結合の実行計画
1 2 3 |
EXPLAIN SELECT カラム名 FROM テーブル1 S INNER JOIN テーブル2 R ON S.id1 = R.id1; |
MySQLの結合はNested Loop結合だけになります。片方のテーブルではtypeに「ALL」が使われて、もう片方のテーブルは「eq_ref」(インデックススキャンのようなもの、JOINに使われる。)が使われます。
サブクエリの種類
MySQLのサブクエリはよく遅いと言われます。実行計画のselect_typeを見れば分かります。
- SUBQUERY
- DEPENDENT SUBQUERY
- DERIVED
結論から言えば遅いのは「DEPENDENT SUBQUERY」になります。
SUBQUERY
DEPENDENT SUBQUERY
相関サブクエリ、MySQLにおいては外部のクエリから評価されて内部のクエリが評価される仕様になっているので、N✖️M回もの計算が行われることになってしまいます。
この記事へのコメントはありません。