Slide 1

Slide 1 text

GroupBy と Distinct Miyazato

Slide 2

Slide 2 text

group by とは ● SQL の SELECT 文において、指定した列の 値が等しい行ごとに表をグループ化する

Slide 3

Slide 3 text

group by とは ● SQL の SELECT 文において、指定した列の 値が等しい行ごとに表をグループ化する 一意の値が取得できる

Slide 4

Slide 4 text

distinct とは ● SQL の SELECT 文において、冗長な重複行 を取り除く

Slide 5

Slide 5 text

distinct とは ● SQL の SELECT 文において、冗長な重複行 を取り除く 一意の値が取得できる

Slide 6

Slide 6 text

group by と distinct を比べる ● 某クラウド、メモリ2GB ● レコード件数 10万件 ● Name カラムには 47都道府県名がランダムに入っている

Slide 7

Slide 7 text

distinct

Slide 8

Slide 8 text

group by

Slide 9

Slide 9 text

同じデータ 取れるなら 同じでしょ

Slide 10

Slide 10 text

Group by は カラム合わせるの 面倒なんだよ

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

group by と distinct を比べる2 ● 某クラウド、メモリ2GB ● レコード件数 10万件 ● Name カラムには 47都道府県名がランダムに入っている

Slide 13

Slide 13 text

検証する DB ● PostgreSQL 7.4

Slide 14

Slide 14 text

検証する DB ● PostgreSQL 7.4 ● PostgreSQL 8.4

Slide 15

Slide 15 text

検証する DB ● PostgreSQL 7.4 ● PostgreSQL 8.4 ● PostgreSQL 9.3

Slide 16

Slide 16 text

検証する方法 ● EXPLAIN で実際の実行時間を計測する ● 検証するパターン – Name カラムにインデックスをはらない ● EXPLAIN ANALYZE select distinct on (name) name FROM pgtest; ● EXPLAIN ANALYZE select distinct name FROM pgtest; ● EXPLAIN ANALYZE select name from pgtest group by name; – Name カラムにインデックスをはる ● EXPLAIN ANALYZE select distinct on (name) name FROM pgtest; ● EXPLAIN ANALYZE select distinct name FROM pgtest; ● EXPLAIN ANALYZE select name from pgtest group by name;

Slide 17

Slide 17 text

スピードを計測 ● PostgreSQL7.4 – EXPLAIN ANALYZE select distinct on (name) name FROM pgtest; ● 実行計画:Unique → Sort → Seq Scan on pgtest ● 実行時間:3223.304 ms – EXPLAIN ANALYZE select distinct name FROM pgtest; ● 実行計画:Unique → Sort → Seq Scan on pgtest ● 実行時間:3206.429 ms – EXPLAIN ANALYZE select name from pgtest group by name; ● 実行計画:HashAggregate → Seq Scan on pgtest ● 実行時間:272.049 ms

Slide 18

Slide 18 text

スピードを計測 ● PostgreSQL7.4(インデックスあり) – EXPLAIN ANALYZE select distinct on (name) name FROM pgtest; ● 実行計画:Unique → Sort → Seq Scan on pgtest ● 実行時間:3219.604 ms – EXPLAIN ANALYZE select distinct name FROM pgtest; ● 実行計画:Unique → Sort → Seq Scan on pgtest ● 実行時間:3217.941 ms – EXPLAIN ANALYZE select name from pgtest group by name; ● 実行計画:HashAggregate → Seq Scan on pgtest ● 実行時間:267.396 ms

Slide 19

Slide 19 text

スピードを計測 ● PostgreSQL8.4 – EXPLAIN ANALYZE select distinct on (name) name FROM pgtest; ● 実行計画:Unique → Sort → Seq Scan on pgtest ● 実行時間:2785.410 ms – EXPLAIN ANALYZE select distinct name FROM pgtest; ● 実行計画:HashAggregate → Seq Scan on pgtest ● 実行時間:233.662 ms – EXPLAIN ANALYZE select name from pgtest group by name; ● 実行計画:HashAggregate → Seq Scan on pgtest ● 実行時間:230.086 ms

Slide 20

Slide 20 text

スピードを計測 ● PostgreSQL8.4(インデックスあり) – EXPLAIN ANALYZE select distinct on (name) name FROM pgtest; ● 実行計画:Unique → Index Scan using pgtest_idx1 on pgtest ● 実行時間:267.068 ms – EXPLAIN ANALYZE select distinct name FROM pgtest; ● 実行計画:Unique → Index Scan using pgtest_idx1 on pgtest ● 実行時間:267.044 ms – EXPLAIN ANALYZE select name from pgtest group by name; ● 実行計画:HashAggregate → Seq Scan on pgtest ● 実行時間:231.749 ms

Slide 21

Slide 21 text

スピードを計測 ● PostgreSQL9.3 – EXPLAIN ANALYZE select distinct on (name) name FROM pgtest; ● 実行計画:Unique → Sort → Seq Scan on pgtest ● 実行時間:2902.322 ms – EXPLAIN ANALYZE select distinct name FROM pgtest; ● 実行計画:HashAggregate → Seq Scan on pgtest ● 実行時間:239.562 ms – EXPLAIN ANALYZE select name from pgtest group by name; ● 実行計画:HashAggregate → Seq Scan on pgtest ● 実行時間:235.504 ms

Slide 22

Slide 22 text

スピードを計測 ● PostgreSQL9.3(インデックスあり) – EXPLAIN ANALYZE select distinct on (name) name FROM pgtest; ● 実行計画:Unique → Index Only Scan using pgtest_idx1 on pgtest ● 実行時間:222.463 ms – EXPLAIN ANALYZE select distinct name FROM pgtest; ● 実行計画:HashAggregate → Seq Scan on pgtest ● 実行時間:239.562 ms – EXPLAIN ANALYZE select name from pgtest group by name; ● 実行計画:HashAggregate → Seq Scan on pgtest ● 実行時間:235.504 ms

Slide 23

Slide 23 text

結論 ● PostgreSQL のバージョンによって動作が違う ● インデックスのありなしでも動作が変わる ● Group by を使ったほうがどのバージョンでも 問題なく安定的に動作する

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

そもそも用途が違う ● Distinct は重複レコードを破棄する ○ 大量データを扱うときにメモリ効率が良い ☓ 一意の値で集計したいときに使えない ● Group by は集計関数 ○ 一意の値で集計が可能 ☓ 大量のデータ件数を貯めこむので メモリ効率が悪い

Slide 26

Slide 26 text

Group by はこうできるだろ?

Slide 27

Slide 27 text

ん?

Slide 28

Slide 28 text

結論 ● PostgreSQL のバージョンによって動作が違う ● インデックスのありなしでも動作が変わる ● Group by を使ったほうがどのバージョンでも 問題なく安定的に動作する ● 用途が違うので、違いを理解してケースバイ ケースで使い分けることが重要

Slide 29

Slide 29 text

結論 ● PostgreSQL のバージョンによって動作が違う ● インデックスのありなしでも動作が変わる ● Group by を使ったほうがどのバージョンでも 問題なく安定的に動作する ● 用途が違うので、違いを理解してケースバイ ケースで使い分けることが重要 ● 都道府県は 46 に減ったらしい ←NEW!!

Slide 30

Slide 30 text

Thank you for your attention.