LoginSignup
3
2

More than 3 years have passed since last update.

【PostgresSQL】IN句をEXIST句に変更したら速度改善された

Posted at

前提

DB:postgres9.4くらい

概要

SQL抽出要件でとあるテーブルには存在して、とあるテーブルには存在しないデータがあり、
その差分を抽出する要件があった。

プライマリーキーはID。
とあるテーブルにはおよそ50万件ほどデータが存在。

結論

EXIST句は早かった。

まずIN句で差分を抽出

30分以上かかり中断。

IN句で書く
-- すべてデータ存在するテーブル
WITH all_data AS (
SELECT ID1,ID2 FROM all_data
)

## データ一部欠損してるテーブル
, missing_data AS (
SELECT ID1,ID2 FROM missing_data 
)

-- 差分検索
SELECT * FROM all_data WHERE (ID1,ID2) NOT IN (SELECT ID1,ID2 FROM missing_data );

EXIST句で差分を抽出

数秒で抽出。

EXIST句で書く
-- すべてデータ存在するテーブル
WITH all_data AS (
SELECT ID1,ID2 FROM all_data
)

-- データ一部欠損してるテーブル
, missing_data AS (
SELECT ID1,ID2 FROM missing_data 
)

-- 差分検索
SELECT * FROM all_data WHERE NOT EXISTS (
  SELECT * FROM missing_data WHERE ID1 = all_data.ID1 AND ID2 = all_data.ID2
);

なぜIN句は遅いのか

以下サイトや他サイトによると、「IN」または「NOT IN」を入れると、クエリエンジンはすべての行を調べて条件が満たされているかどうかを一々確認する「テーブルフルスキャン」を行うから遅いとのこと。
https://itnews.org/news_contents/sql-201-10-ways-to-tweak-slow-running-queries-3pkb

補足

未検証だがPostgres以外だと上記通りIN句が遅いとは限らないとのこと。

以上

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2