9月 152013
 

後輩が複数件あるデータからユニークなデータを作る時に distinct
を使っていた。 俺は group by
の方が高速だよと何か読んだことがあったのでちょっと驚いた。

とりあえず指摘はしたんだけど、どうにも腑に落ちなかったので、実際にどちらが良いのか自分なりに調べてみた。

共通条件

  • 某クラウド、メモリ 2GB
  • レコード件数 10万件
  • name には 47都道府県名がランダムに入っている ○使用テーブル

条件1:PostgreSQL 7.4 の時

  • EXPLAIN ANALYZE select distinct on (name) name FROM pgtest;
    Unique ->Sort ->Seq Scan on pgtest

    Total runtime: 3223.304 ms

  • EXPLAIN ANALYZE select distinct name FROM pgtest;
    Unique ->Sort ->Seq Scan on pgtest

    Total runtime: 3206.429 ms

  • EXPLAIN ANALYZE select name from pgtest group by name;
    HashAggregate ->Seq Scan on pgtest

    Total runtime: 272.049 ms

条件2:PostgreSQL 7.4 で name にインデックスをはった時

  • EXPLAIN ANALYZE select distinct on (name) name FROM pgtest;
    Unique ->Sort ->Seq Scan on pgtest

    Total runtime: 3219.604 ms

  • EXPLAIN ANALYZE select distinct name FROM pgtest;
    Unique ->Sort ->Seq Scan on pgtest

    Total runtime: 3217.941 ms

  • EXPLAIN ANALYZE select name from pgtest group by name;
    HashAggregate ->Seq Scan on pgtest

    Total runtime: 267.396 ms

条件3:PostgreSQL 8.4 の時

  • EXPLAIN ANALYZE select distinct on (name) name FROM pgtest;
    Unique ->Sort ->Seq Scan on pgtest

    Total runtime: 2785.410 ms

  • EXPLAIN ANALYZE select distinct name FROM pgtest;
    HashAggregate ->Seq Scan on pgtest

    Total runtime: 233.662 ms

  • EXPLAIN ANALYZE select name from pgtest group by name;
    HashAggregate ->Seq Scan on pgtest

    Total runtime: 230.086 ms

条件4:PostgreSQL 8.4 で name にインデックスをはった時

  • EXPLAIN ANALYZE select distinct on (name) name FROM pgtest;
    Unique ->Index Scan using pgtest_idx1 on pgtest

    Total runtime: 267.068 ms

  • EXPLAIN ANALYZE select distinct name FROM pgtest; Unique ->Index
    Scan using pgtest_idx1 on pgtest

    Total runtime: 267.044 ms

  • EXPLAIN ANALYZE select name from pgtest group by name;
    HashAggregate ->Seq Scan on pgtest

    Total runtime:231.749 ms

条件5:PostgreSQL 9.3 の時

  • EXPLAIN ANALYZE select distinct on (name) name FROM pgtest;
    Unique ->Sort ->Seq Scan on pgtest

    Total runtime: 2902.322 ms

  • EXPLAIN ANALYZE select distinct name FROM pgtest;
    HashAggregate ->Seq Scan on pgtest

    Total runtime:239.562 ms

  • EXPLAIN ANALYZE select name from pgtest group by name;
    HashAggregate ->Seq Scan on pgtest

    Total runtime:235.504 ms

条件6:PostgreSQL 9.3 で name にインデックスをはった時

  • EXPLAIN ANALYZE select distinct on (name) name FROM pgtest;
    Unique ->Index Only Scan using pgtest_idx1 on pgtest

    Total runtime: 222.463 ms

  • EXPLAIN ANALYZE select distinct name FROM pgtest;
    HashAggregate ->Seq Scan on pgtest

    Total runtime: 235.667 ms

  • EXPLAIN ANALYZE select name from pgtest group by name;
    HashAggregate ->Seq Scan on pgtest

    Total runtime: 232.319 ms

俺なりの結論としては、バージョンやインデックスに左右されていない group by の方が良い。


  One Response to “group by と distinct 速度評価”

  1. […] 以前に group by と distinct 速度評価 として調査したのは、次の資料を作るためだった。 […]

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">