トップへ(mam-mam.net/)

MariaDB(MySQL)で副問い合わせを使うと遅い時の対応策

MariaDB(MySQL)で副問い合わせを使うと遅い時の対応策

MariaDB(MySQL)でWhere句やjoinのon句に使用するカラムにインデックスが付いていないと処理速度が遅いです。
例えばサブクエリでGroup By等でSUM,COUNT,MAX関数等を使って新たに名前を付けたカラム等が該当します。
テンポラリテーブル(一時テーブル)を作成してインデックスを付けて、サブクエリの実行結果を入れれば処理速度は格段に速くなる可能性があります。

テンポラリーテーブルを使う方法

例えばテーブル構造が以下とします。

table1
カラム名
column11INT
column12VARCHAR(255)
table2
カラム名
column21INT
column22VARCHAR(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;