このページは、テストデータを用いて PostgreSQL の実行計画の検証を行った結果を記載するページです。
目次
注意
- 常に同じ結果・速度になるわけではありません (ある程度の参考のために記載しています)
前提条件
データは下記のデータを用います。
- 部署マスタ (部署ID, 部署名) - 100件
- 部署ID = bigserial PRIMARY KEY
- 部署名 = varchar(255)
- 従業員マスタ (従業員ID, 社員名, 性別, 部署ID) - 100万件
- 従業員ID = bigserial PRIMARY KEY
- 社員名 = varchar(255) (インデックスあり)
- 性別 = integer (1 = 男性, 2 = 女性。インデックスあり)
- 部署ID = bigint (部署マスタ.部署ID の外部キー制約。インデックスあり)
テストデータ
クエリの例と結果
一般的なクエリ
OR と IN (主キー検索の比較)
- IN にしたほうが Index Scan のみになりコストが低い
IN と EXISTS
インデックスが設定されている項目の検索
- インデックスを設定していても、区分の種類やデータ量によってうまく使えるケースと使えないケース (使っても意味がない) がある (Seq Scan になることもある)
JOIN (LEFT JOIN, INNER JOIN の比較)
(従業員マスタと部署マスタを結合するクエリの比較。部署に未所属の従業員が100名いるため、件数は INNER JOIN が100件少なくなる)
COUNT() の比較
- インデックスが使えるケースでも、
COUNT
の違いで実行計画に違いが出る
COUNT(*)
はインデックスの情報だけで件数が判断できるので Index Only Scan になる
COUNT(項目)
は項目の値が NULL かどうかで件数が変わるため、Index Only Scan にできない (インデックスを確認した後に項目の値を確認しにいく必要がある)
別テーブルの件数取得クエリの比較
(「部署名, 部署ごとの従業員数」を算出するクエリの比較)
- ①のケースでは「部署マスタの100件 × 従業員マスタの件数取得 (SubPlan 1) の合計コスト ≒ 全体の合計コスト」になっているが、実際の速度的には②と大差がない (少し速い)
- 部署マスタを1万件に増やした場合でも、速度的には①のほうが少し速い