おさかな日誌

魚類がプログラミング

MySQL のサブクエリで気をつけとくこと

MySQL のクエリ最適化のために調べてたらサブクエリの話題が出てて、「相関関係のあるサブクエリは遅い」とか書いてあって、サブクエリ周りで知っておくといいこと得られたので書いておく。なぜMySQLのサブクエリは遅いのか。 を読んで手元のデータベースで適当に試してなるほどなるほど言った記録。


MySQL の EXPLAIN 氏によるサブクエリの分け方としては

  • PRIMARY 外部クエリを示す。
  • SUBQUERY 相関関係のないサブクエリ。
  • DEPENDENT SUBQUERY 相関関係のあるサブクエリ。
  • UNCACHEABLE SUBQUERY 実行する度に結果が変わる可能性のあるサブクエリ。
  • DERIVED FROM句で用いられているサブクエリ。

があるようだ。

DEPENDENT SUBQUERYおよびUNCACHEABLE SUBQUERYの場合はサブクエリが行の評価の度に実行される

と書いてあったので、なるべく避けたい存在かもしれない、と思って Dependent SubQuery を調べてみた。

手元のデータベースで適当にサブクエリをいくつか書いていて「あれ?これ相関関係あるの?毎回実行しなくてもいいんじゃ」というクエリがあった。調べてみると:

MySQLは内部的にINを直接処理することができないので、EXISTSに変換することでSQL的には相関のないサブクエリも相関サブクエリになってしまうのである。

なるほど。適当にサブクエリを書くとまず IN (SELECT ....) の形が思い浮かんで IN 句を使っていた。

サブクエリでインデックスをつけるべきカラムは、サブクエリが結果を返すカラム

なるほど。