かっこ株式会社インターン生のK.T.です。
かっこ株式会社ではデータ分析だったりRPA構築等の業務のためだったりにSQLを多用します。
その中で、
「単に正しい結果を出せばいい」
だけではなく、
「少しでも早く正しい結果を返すことで業務効率をアップさせる」
「SQLは書き方次第で、早くも遅くもなったりする」
ことを実感したことがあったので、Qiitaに残します。
環境
AWSのRDS
PostgreSQL 10.6
東京リージョンのインスタンスクラスはdb.t2.large で実施
要件
hogeが全体のデータで、fugaが一部のデータだとして、
「hogeからfugaとのidが一致していないものを抽出したい」という要件。
結構よくある話だと思います。
※ここでは例としてidのみSELECTするSQLにしました。
コード
まず、WHERE句でidが一致していないという条件を指定すると、、、、
SELECT
hoge.id
FROM
hoge
WHERE
id NOT IN (SELECT id FROM fuga);
fugaのレコード数が数百万レベルになると処理に数時間以上かかりました。
これと出力内容を変えず、文法を以下に変えると、、、
SELECT
hoge.id
FROM
hoge
LEFT JOIN
(SELECT id FROM fuga) fuga ON hoge.id = fuga.id
WHERE
fuga.id IS NULL;
数十秒で結果が返ってきました。
どうやらWHERE句で毎回fugaを呼び出していたのが問題だった模様で、
fugaのレコード数が1000件程度では処理時間に差がつかなかったが、
レコード数が膨大になると処理時間に大きく差がつくようでした。
ちなみに、hogeからfugaとidが一致しているものを抽出するなら、
SELECT
hoge.id
FROM
hoge
RIGHT JOIN
(SELECT id FROM fuga) fuga ON hoge.id = fuga.id
となると思います。INNER JOINを使っても同じ結果になるはず。
後記
文法によって処理速度が激変することを再認識できた。