MariaDB(MySQL)で副問い合わせを使うと遅い時の対応策
MariaDB(MySQL)でWhere句やjoinのon句に使用するカラムにインデックスが付いていないと処理速度が遅いです。
例えばサブクエリでGroup By等でSUM,COUNT,MAX関数等を使って新たに名前を付けたカラム等が該当します。
テンポラリテーブル(一時テーブル)を作成してインデックスを付けて、サブクエリの実行結果を入れれば処理速度は格段に速くなる可能性があります。
テンポラリーテーブルを使う方法
テンポラリテーブルは以下のような構文で作成できます。
テンポラリテーブルは現在のセッション内だけで有効なテーブルを作成し、セッションが終了した時に、自動的にテーブルが削除されます。
CREATE TEMPORARY TABLE テンポラリテーブル名(カラム名 型, ・・・) AS SELECT文のSQL
例えばテーブル構造が以下とします。
カラム名 | 型 |
---|---|
column11 | INT (PRIMARY KEY) |
column12 | VARCHAR(255) |
カラム名 | 型 |
---|---|
column21 | INT (PRIMARY KEY) |
column22 | VARCHAR(255) |
例えば以下のSQLが遅いとします。
(以下のようなSQLを実行することはほぼ無いですが、あくまで例なので大目に見てください)
SELECT table2.column21, table2.column22, tb1.column12 FROM table2
INNER JOIN
(SELECT SUM(column11) AS column11, column12 FROM table1 GROUP BY column12) AS tb1
ON table2.column21=tb1.column11;
サブクエリの箇所だけテンポラリテーブルを作成し、元のSQLのサブクエリーの箇所にテンポラリテーブルを使用します。
-- テンポラリテーブル「tmp1」を作成する CREATE TEMPORARY TABLE tmp1( column11 INT, column12 VARCHAR(255), INDEX idx_tmp1_column11(column11) -- インデックスを生成 ) AS SELECT SUM(column11) AS column11, column12 FROM table1 GROUP BY column12; -- サブクエリを tmp1 として使用する SELECT table2.column21, tmp1.column12 FROM table2 INNER JOIN tmp1 ON table2.column21=tmp1.column11; -- テンポラリテーブル「tmp1」を削除する DROP TEMPORARY TABLE IF EXISTS tmp1;