SlideShare a Scribd company logo
第6回 PostgreSQLアンカンファレンス 1/21
第6回 PostgreSQLアンカンファレンス
[9.5新機能]
追加されたGROUP BY機能の使い方
Kosuke Kida
SlideShareへの公開にあたり、2015年12月12日(土)アンカンファレンス当日の発表後に
いただいたコメントを元に一部項目を追加しています。
主な追記箇所
 P.9  分析系の用途でDB選択時、本機能追加がどう影響するかコメント
 P.10- CUBEの実行計画をより分かりやすいものに変更、スライド追加
 P.20- 最後に挙げた疑問点のうち、解決の糸口になりそうな情報を発表後の質疑から追記
※追記個所は本テキストボックスと同色の枠で記載
第6回 PostgreSQLアンカンファレンス 2/21
アジェンダ
9.5の新機能を勉強中のうちの一つを発表してみる
● 標準SQLへの対応
● 良いところ
● 実用シーンを考察
● マニュアルにないところの疑問
仕事ではPostgreSQL、Postgres Plusのプリセールス、他DBからの移行評価、環境構築、
トラブル対応などやっています。(PostgreSQLを知らない)顧客対応がほとんどの中で、
どんな情報が有益か考える中で、ベータ版時点から自分で触って、使い方、使いどころを
掴もうと試みています。(Ver9.3ぐらいから)
 ・特にアンカンファレンスが開催されるようになって、新機能に対する
  初めの一歩のハードルが大きく下がった
 ・どういうシーンで使えるかまで考えておくと、お客様からの反応が大きい
 ・分析系の用途でPostgreSQLはどこまで使えるか、という相談は最近多いので
  BRINインデックスとか、集計構文とか、結構注目されてる
第6回 PostgreSQLアンカンファレンス 3/21
標準SQLへの対応
1クエリで複数の集計を組合せて取得
● GROUP BY GROUPING SETS
✔ こんな売上実績データ(result表、item表、shop表をJOIN)
SELECT r_date::date date,s_name,i_name,r_qt,r_qt * i_price sales
FROM result
JOIN item ON r_item = i_code
JOIN shop ON i_shop = s_id
ORDER BY r_date;
r_date | s_name | i_name | r_qt | sales
------------+------------+--------------+------+--------
2015-10-30 | Paul Smith | スラックス | 1 | 20000
2015-10-30 | Dior | シャツ | 2 | 60000
2015-10-30 | Dior | 冬ジャケット | 1 | 100000
2015-10-30 | Paul Smith | シャツ | 1 | 15000
2015-10-31 | DIESEL | ダメージB | 1 | 35000
2015-10-31 | DIESEL | ストレート | 2 | 50000
2015-10-31 | Dior | 冬ジャケット | 1 | 100000
2015-10-31 | Dior | シャツ | 1 | 30000
2015-11-01 | Paul Smith | シャツ | 3 | 45000
2015-11-02 | DIESEL | ダメージA | 1 | 30000
第6回 PostgreSQLアンカンファレンス 4/21
標準SQLへの対応
1クエリで複数の集計を組合せて取得
● GROUP BY GROUPING SETS
✔ 日別の売上集計と店舗毎の売り上げ集計が欲しい
SELECT r_date::date date
     ,sum(r_qt * i_price) sum
FROM result
JOIN item ON r_item = i_code
JOIN shop ON i_shop = s_id
GROUP BY date ORDER BY sum DESC;
date | sum
------------+--------
2015-10-31 | 215000
2015-10-30 | 195000
2015-11-08 | 50000
2015-11-01 | 45000
2015-11-03 | 45000
2015-11-02 | 45000
2015-11-07 | 40000
2015-11-06 | 30000
 :
SELECT s_name shop
     ,sum(r_qt * i_price) sum
FROM result
JOIN item ON r_item = i_code
JOIN shop ON i_shop = s_id
GROUP BY shop ORDER BY sum DESC;
shop | sum
------------+--------
Dior | 350000
DIESEL | 195000
Paul Smith | 165000
(3 行)
第6回 PostgreSQLアンカンファレンス 5/21
標準SQLへの対応
1クエリで複数の集計を組合せて取得
● GROUP BY GROUPING SETS
✔ 1クエリで店舗別、日別、総計を取得
SELECT s_name shop,r_date::date date,sum(r_qt * i_price) sum
FROM result
JOIN item ON r_item = i_code
JOIN shop ON i_shop = s_id
GROUP BY GROUPING SETS ((shop),(date),());
shop | date | sum
------------+------------+--------
DIESEL | | 195000
Dior | | 350000
Paul Smith | | 165000
| | 710000 /*総計*/
| 2015-10-30 | 195000
| 2015-10-31 | 215000
| 2015-11-01 | 45000
| 2015-11-02 | 45000
| 2015-11-03 | 45000
             :
第6回 PostgreSQLアンカンファレンス 6/21
標準SQLへの対応
1クエリで複数の集計を組合せて取得
● ROLLUP
✔ 1クエリで店舗-日付の組合せ、店舗別売上、総計を取得
SELECT s_name shop,r_date::date date
     ,sum(r_qt * i_price) sum
FROM result
JOIN item ON r_item = i_code
JOIN shop ON i_shop = s_id
GROUP BY ROLLUP ((shop),(date));
shop | date | sum
------------+------------+--------
DIESEL | 2015-10-31 | 85000
DIESEL | 2015-11-02 | 30000
DIESEL | 2015-11-06 | 30000
DIESEL | | 195000
Dior | 2015-10-30 | 160000
Dior | 2015-10-31 | 130000
Dior | | 350000
Paul Smith | 2015-10-30 | 35000
Paul Smith | 2015-11-01 | 45000
Paul Smith | 2015-11-02 | 15000
Paul Smith | | 165000
| | 710000
(結果はスライド用にところどころ省略)
第6回 PostgreSQLアンカンファレンス 7/21
標準SQLへの対応
1クエリで複数の集計を組合せて取得
● CUBE
✔ 1クエリで店舗-日付の組合せ、店舗別売上、日別売上、総計を取得
SELECT s_name shop,r_date::date date
     ,sum(r_qt * i_price) sum
FROM result
JOIN item ON r_item = i_code
JOIN shop ON i_shop = s_id
GROUP BY CUBE ((shop),(date));
shop | date | sum
------------+------------+--------
DIESEL | 2015-10-31 | 85000
DIESEL | 2015-11-02 | 30000
DIESEL | | 195000
Dior | 2015-10-30 | 160000
Dior | 2015-11-08 | 30000
Dior | | 350000
Paul Smith | 2015-10-30 | 35000
Paul Smith | 2015-11-01 | 45000
Paul Smith | 2015-11-02 | 15000
Paul Smith | 2015-11-08 | 20000
Paul Smith | | 165000
| | 710000
| 2015-10-30 | 195000
| 2015-10-31 | 215000
| 2015-11-08 | 50000
(結果はスライド用にところどころ省略)
第6回 PostgreSQLアンカンファレンス 8/21
良いところ(教科書的な)
1クエリで結果を取得できるので
● APとDBのやりとりの回数を削減
日別集計
店舗別集計
総計
あらゆる組合せ
第6回 PostgreSQLアンカンファレンス 9/21
良いところ(教科書的な)
1クエリで結果を取得できるので
● SeqScanの回数を削減
日別集計 30分
店舗別集計 30分
総計 30分
あらゆる組合せ 1時間
分析用途で現状PostgreSQLが
どの程度使えるのか?
という問いに対して、回答は、
今のところ、リアルタイム性を
どこまで求めるかだと思う。
---
左記に近い実際にあった例だと、
1日1回、オンライン系のシステム
から実績データを取込み、夜間
バッチで加工・集計して、複数の
Mビューで保持しとく使い方。
夜間のうちに完了するかどうかが
DB選定の肝になっていた。
構文が追加された事による
実行計画の効率化が採用可否の
分岐点になりそうな予感。
---
※ちなみにOracle EEで限界まで
チューニングして同じことをやると
1秒で結果が得られるとか、
それぐらいのスピード感になりそうな話。
「こ、これがリアルタイムか・・・ぐぬぬ」
第6回 PostgreSQLアンカンファレンス 10/21
実用シーンを考察
実行計画はどうなるか
● CUBEの実行計画を確認する
 
 
 
 
 
 
 
✔ このテーブルに対して従来の各項目別にGROUP BYすると
– 全件のカウント 306.755 ms
– アイテム種別カウント 718.326 ms
– 売上日別カウント 596.246 ms
– 売上店舗別カウント 609.198 ms  計2200 msぐらい
✔ CUBEでは加えて「日別-アイテム別」や「日別-店舗別」等、全組合せ集計結果を取得
-- CUBEのみの実行計画を見たい。
-- JOINの影響をなくすため、類似のデータを単一のテーブルで用意
-- 100万件超えるまで、適当にINSERT INTO huge SELECT * FROM result JOIN item・・・
postgres=# SELECT count(*) FROM huge;
count
---------
1310720
postgres=# show work_mem;
work_mem
----------
4MB   -- デフォルト
第6回 PostgreSQLアンカンファレンス 11/21
実用シーンを考察
実行計画はどうなるか
● SeqScanの回数を削減
✔ ただし、ソートが激増してDISKソートになると劇遅(2.2秒→7.8秒)
postgres=# EXPLAIN ANALYZE
postgres-# SELECT sales_date::date,shop,kind,count(*) FROM huge
postgres-# GROUP BY CUBE ((sales_date::date),(shop),(kind));
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------
GroupAggregate (cost=194723.79..566418.36 rows=336 width=26) (actual time=2671.543..7775.091 rows=69 loops=1)
Group Key: ((sales_date)::date), shop, kind
Group Key: ((sales_date)::date), shop
Group Key: ((sales_date)::date)
Group Key: ()
Sort Key: kind, ((sales_date)::date)
Group Key: kind, ((sales_date)::date)
Group Key: kind
Sort Key: shop, kind
Group Key: shop, kind
Group Key: shop
-> Sort (cost=194723.79..198000.59 rows=1310720 width=26) (actual time=2501.926..3181.656 rows=1310720 loops=1)
Sort Key: ((sales_date)::date), shop, kind
Sort Method: external merge Disk: 42216kB
-> Seq Scan on huge (cost=0.00..30182.00 rows=1310720 width=26)
(actual time=0.023..290.534 rows=1310720 loops=1)
Planning time: 0.141 ms
Execution time: 7788.108 ms
(17 行)
第6回 PostgreSQLアンカンファレンス 12/21
実用シーンを考察
実行計画はどうなるか
● SeqScanの回数を削減
✔ ただし、ソートが激増してDISKソートになると劇遅
✔ work_memの増加で対処(2.2秒→7.8秒→3.0秒)
postgres=# set work_mem to '200MB';
SET
postgres=# EXPLAIN ANALYZE
SELECT sales_date::date,shop,kind,count(*) FROM huge
GROUP BY CUBE ((sales_date::date),(shop),(kind));
QUERY PLAN
--------------------------------------------------------------------------------------------------------------------
GroupAggregate (cost=163363.79..472338.36 rows=336 width=26) (actual time=1041.637..2986.535 rows=69 loops=1)
Group Key: ((sales_date)::date), shop, kind
Group Key: ((sales_date)::date), shop
Group Key: ((sales_date)::date)
Group Key: ()
Sort Key: kind, ((sales_date)::date)
Group Key: kind, ((sales_date)::date)
Group Key: kind
Sort Key: shop, kind
Group Key: shop, kind
Group Key: shop
-> Sort (cost=163363.79..166640.59 rows=1310720 width=26) (actual time=978.680..1147.774 rows=1310720 loops=1)
Sort Key: ((sales_date)::date), shop, kind
Sort Method: quicksort Memory: 149662kB
-> Seq Scan on huge (cost=0.00..30182.00 rows=1310720 width=26)
(actual time=0.030..316.498 rows=1310720 loops=1)
Planning time: 0.238 ms
Execution time: 3006.193 ms
(17 行)
第6回 PostgreSQLアンカンファレンス 13/21
実用シーンを考察
実行計画はどうなるか
● CUBEの実行計画を確認する
✔ このテーブルに対して従来の各項目別にGROUP BYすると
– 全件のカウント 306.755 ms
– アイテム種別カウント 718.326 ms
– 売上日別カウント 596.246 ms
– 売上店舗別カウント 609.198 ms  計2200 msぐらい
✔ CUBEでは加えて「日別-アイテム別」や「日別-店舗別」等、全組合せ集計結果を取得
– 全件のカウント
– アイテム種別カウント
– 売上日別カウント
– 売上店舗別カウント
– 日別-アイテム別カウント
– 日別-店舗別カウント
– アイテム別ー店舗別カウント
– 日別ーアイテム別ー店舗別カウント   計3000 ms ぐらい
第6回 PostgreSQLアンカンファレンス 14/21
実用シーンを考察
クロス集計までDBで行う
● クロス集計
✔ 何かのアイテムに関する街頭調査結果みたいなイメージ
✔ それぞれの枠に対してクエリを書いてデータを取得する必要があった
✔ CUBEならこれを1クエリで取得できているので、
あとは「行列変換して表示」できればOKなのだが。
性別 男 女 合計
年代 ~20代 それ以上 ~20代 それ以上 --
アイテムA 10人 10人 80人 100人 200人
アイテムB 20人 10人 50人 80人 160人
アイテムC 30人 10人 50人 50人 140人
合計 60人 30人 180人 230人 500人
第6回 PostgreSQLアンカンファレンス 15/21
実用シーンを考察
1クエリで複数の集計を組合せて取得
● CUBEでは、クロス集計表を埋める結果はすべて取得済み
✔ 1クエリで店舗-日付の組合せ、店舗別売上、日別売上、総計を取得
SELECT s_name shop,r_date::date date
     ,sum(r_qt * i_price) sum
FROM result
JOIN item ON r_item = i_code
JOIN shop ON i_shop = s_id
GROUP BY CUBE ((shop),(date));
shop | date | sum
------------+------------+--------
DIESEL | 2015-10-31 | 85000
DIESEL | 2015-11-02 | 30000
DIESEL | | 195000
Dior | 2015-10-30 | 160000
Dior | 2015-11-08 | 30000
Dior | | 350000
Paul Smith | 2015-10-30 | 35000
Paul Smith | 2015-11-01 | 45000
Paul Smith | 2015-11-02 | 15000
Paul Smith | 2015-11-08 | 20000
Paul Smith | | 165000
| | 710000
| 2015-10-30 | 195000
| 2015-10-31 | 215000
| 2015-11-08 | 50000
(結果はスライド用にところどころ省略)
shop | date | sum
------------+------------+--------
DIESEL | 2015-10-31 | 85000
DIESEL | 2015-11-02 | 30000
DIESEL | | 195000
Dior | 2015-10-30 | 160000
Dior | 2015-11-08 | 30000
Dior | | 350000
Paul Smith | 2015-10-30 | 35000
Paul Smith | 2015-11-01 | 45000
Paul Smith | 2015-11-02 | 15000
Paul Smith | 2015-11-08 | 20000
Paul Smith | | 165000
| | 710000
| 2015-10-30 | 195000
| 2015-10-31 | 215000
| 2015-11-08 | 50000
(結果はスライド用にところどころ省略)
第6回 PostgreSQLアンカンファレンス 16/21
実用シーンを考察
クロス集計までDBで完結する
● クロス集計
✔ tablefuncエクステンションでクロス集計
# rpm -ivh postgresql95-contrib-9.5-beta1_1PGDG.el6.x86_64.rpm
# psql
postgres=# create extension tablefunc;
CREATE EXTENSION
第6回 PostgreSQLアンカンファレンス 17/21
実用シーンを考察
クロス集計までDBで完結する
● クロス集計
✔ tablefuncエクステンションでクロス集計
--CUBE結果をMViewに保存(tablefuncの構文をシンプルにしたいので今回はコレで。)
CREATE MATERIALIZED VIEW mv_cube AS
SELECT sales_date::date,shop,kind,count(*) FROM result
GROUP BY CUBE ((sales_date::date),(shop),(kind));
--crosstab関数をかませて結果を整形
SELECT * FROM crosstab('
SELECT date,COALESCE(shop,''null''),sum FROM mv_cube     --整形したいクエリ
ORDER BY date
','
SELECT DISTINCT COALESCE(shop,''null'') shop FROM mv_cube --2番目の引数は
ORDER BY shop NULLS LAST --結果の列名に対応
')
AS sales (
date date
,"DIESEL" numeric
,"Dior" numeric
,"Paul Smith" numeric
,"daily sum" numeric
);
第6回 PostgreSQLアンカンファレンス 18/21
date | DIESEL | Dior | Paul Smith | daily sum
------------+--------+--------+------------+-----------
2015-10-30 | | 160000 | 35000 | 195000
2015-10-31 | 85000 | 130000 | | 215000
2015-11-01 | | | 45000 | 45000
2015-11-02 | 30000 | | 15000 | 45000
2015-11-03 | 25000 | | 20000 | 45000
2015-11-04 | | 30000 | | 30000
2015-11-05 | | | 15000 | 15000
2015-11-06 | 30000 | | | 30000
2015-11-07 | 25000 | | 15000 | 40000
2015-11-08 | | 30000 | 20000 | 50000
| 195000 | 350000 | 165000 | 710000
(11 行)
実用シーンを考察
クロス集計までDBで完結する
● クロス集計
✔ tablefuncエクステンションでクロス集計
第6回 PostgreSQLアンカンファレンス 19/21
date | DIESEL | Dior | Paul Smith | daily sum
------------+--------+--------+------------+-----------
2015-10-30 | | 160000 | 35000 | 195000
2015-10-31 | 85000 | 130000 | | 215000
2015-11-01 | | | 45000 | 45000
2015-11-02 | 30000 | | 15000 | 45000
2015-11-03 | 25000 | | 20000 | 45000
2015-11-04 | | 30000 | | 30000
2015-11-05 | | | 15000 | 15000
2015-11-06 | 30000 | | | 30000
2015-11-07 | 25000 | | 15000 | 40000
2015-11-08 | | 30000 | 20000 | 50000
| 195000 | 350000 | 165000 | 710000
(11 行)
実用シーンを考察
クロス集計までDBで完結する
● クロス集計
✔ tablefuncエクステンションでクロス集計
date | DIESEL | Dior | Paul Smith | daily sum
------------+--------+--------+------------+-----------
2015-10-30 | | 160000 | 35000 | 195000
2015-10-31 | 85000 | 130000 | | 215000
2015-11-01 | | | 45000 | 45000
2015-11-02 | 30000 | | 15000 | 45000
2015-11-03 | 25000 | | 20000 | 45000
2015-11-04 | | 30000 | | 30000
2015-11-05 | | | 15000 | 15000
2015-11-06 | 30000 | | | 30000
2015-11-07 | 25000 | | 15000 | 40000
2015-11-08 | | 30000 | 20000 | 50000
| 195000 | 350000 | 165000 | 710000
(11 行)
第6回 PostgreSQLアンカンファレンス 20/21
マニュアルで見つけられなかった疑問
grouping関数の存在と役割
● 標準SQLやOracleの構文を見ていると登場するGROUPING関数
✔ 指定してみたらPostgreSQL 9.5でも使えた
✔ しかしマニュアルに無く、pg_procなどからも定義が探せない
SELECT grouping(s_name) AS g1
,grouping(r_date::date) AS g2
,grouping(s_name,r_date::date) AS gX
,s_name shop,r_date::date date,sum(r_qt * i_price) sum
FROM result
JOIN item ON r_item = i_code
JOIN shop ON i_shop = s_id
GROUP BY GROUPING SETS ((shop),(date),());
g1 | g2 | gx | shop | date | sum
----+----+----+------------+------------+--------
0 | 1 | 1 | DIESEL | | 195000
0 | 1 | 1 | Dior | | 350000
0 | 1 | 1 | Paul Smith | | 165000
1 | 1 | 3 | | | 710000
1 | 0 | 2 | | 2015-10-30 | 195000
1 | 0 | 2 | | 2015-10-31 | 215000
この実行例が意味をあらわしている?
本当にnullだったか、グルーピングされた結果かどうか
gXの3は、2進数の11?項目が増えたら?
第6回 PostgreSQLアンカンファレンス 21/21
マニュアルで見つけられなかった疑問
grouping関数の存在と役割
● 標準SQLやOracleの構文を見ていると登場するGROUPING関数
✔ 指定してみたらPostgreSQL 9.5でも使えた
✔ しかしマニュアルに無く、pg_procなどからも定義が探せない
– パーサーのソースコード中にそれらしき定義がありそう
– http://doxygen.postgresql.org/で検索してみたら、確かにそんな感じ
groupingは関数ではなく、構造体?の扱い
パーサーのコードの中にありそう
詳細は後日確認します!

More Related Content

PDF
Jpug study-pq 20170121
Kosuke Kida
 
PDF
Chugokudb18_2
Kosuke Kida
 
PDF
Chugoku db 17th-postgresql-9.6
Toshi Harada
 
PDF
Chugoku db 17th-lt-kly
Toshi Harada
 
PDF
DynamoDB MyNA・JPUG合同DB勉強会 in 東京
Yuko Mori
 
PDF
JSONBはPostgreSQL9.5でいかに改善されたのか
NTT DATA OSS Professional Services
 
PDF
PostgreSQLレプリケーション(pgcon17j_t4)
Kosuke Kida
 
PDF
Lt ingaoho-jsonb+postgeres fdw
Toshi Harada
 
Jpug study-pq 20170121
Kosuke Kida
 
Chugokudb18_2
Kosuke Kida
 
Chugoku db 17th-postgresql-9.6
Toshi Harada
 
Chugoku db 17th-lt-kly
Toshi Harada
 
DynamoDB MyNA・JPUG合同DB勉強会 in 東京
Yuko Mori
 
JSONBはPostgreSQL9.5でいかに改善されたのか
NTT DATA OSS Professional Services
 
PostgreSQLレプリケーション(pgcon17j_t4)
Kosuke Kida
 
Lt ingaoho-jsonb+postgeres fdw
Toshi Harada
 

What's hot (20)

PDF
Chugoku db 20th-postgresql-10-pub
Toshi Harada
 
PDF
Chugokudb18_1
Kosuke Kida
 
PDF
KOF2015 PostgreSQL 9.5
Toshi Harada
 
PDF
Pgunconf 20121212-postgeres fdw
Toshi Harada
 
PDF
PostgreSQL 10 新機能 @オープンセミナー香川 2017
Shigeru Hanada
 
PDF
Hackers Champloo 2016 postgresql-9.6
Toshi Harada
 
PDF
PostgreSQL10徹底解説
Masahiko Sawada
 
PDF
PostgreSQL 10 新機能 @OSC 2017 Fukuoka
Shigeru Hanada
 
PDF
pg_bigmを用いた全文検索のしくみ(前編)
NTT DATA OSS Professional Services
 
PDF
Chugokudb study-20150131
Toshi Harada
 
PDF
my sql-postgresql勉強会#6 LT 私的なPostgreSQLの楽しみ方
Toshi Harada
 
PDF
アナリティクスをPostgreSQLで始めるべき10の理由@第6回 関西DB勉強会
Satoshi Nagayasu
 
PDF
PGCon.jp 2014 jsonb-datatype-20141205
Toshi Harada
 
PDF
Postgre sql9.3新機能紹介
Daichi Egawa
 
PDF
Vacuum徹底解説
Masahiko Sawada
 
PDF
Webで役立つRDBの使い方
Soudai Sone
 
PDF
pg_bigm(ピージー・バイグラム)を用いた全文検索のしくみ(後編)
Masahiko Sawada
 
PDF
PostgreSQL9.3新機能紹介
NTT DATA OSS Professional Services
 
PDF
GPUとSSDがPostgreSQLを加速する~クエリ処理スループット10GB/sへの挑戦~ [DB Tech Showcase Tokyo/2017]
Kohei KaiGai
 
PDF
Jpug study-postgre sql-10-pub
Toshi Harada
 
Chugoku db 20th-postgresql-10-pub
Toshi Harada
 
Chugokudb18_1
Kosuke Kida
 
KOF2015 PostgreSQL 9.5
Toshi Harada
 
Pgunconf 20121212-postgeres fdw
Toshi Harada
 
PostgreSQL 10 新機能 @オープンセミナー香川 2017
Shigeru Hanada
 
Hackers Champloo 2016 postgresql-9.6
Toshi Harada
 
PostgreSQL10徹底解説
Masahiko Sawada
 
PostgreSQL 10 新機能 @OSC 2017 Fukuoka
Shigeru Hanada
 
pg_bigmを用いた全文検索のしくみ(前編)
NTT DATA OSS Professional Services
 
Chugokudb study-20150131
Toshi Harada
 
my sql-postgresql勉強会#6 LT 私的なPostgreSQLの楽しみ方
Toshi Harada
 
アナリティクスをPostgreSQLで始めるべき10の理由@第6回 関西DB勉強会
Satoshi Nagayasu
 
PGCon.jp 2014 jsonb-datatype-20141205
Toshi Harada
 
Postgre sql9.3新機能紹介
Daichi Egawa
 
Vacuum徹底解説
Masahiko Sawada
 
Webで役立つRDBの使い方
Soudai Sone
 
pg_bigm(ピージー・バイグラム)を用いた全文検索のしくみ(後編)
Masahiko Sawada
 
PostgreSQL9.3新機能紹介
NTT DATA OSS Professional Services
 
GPUとSSDがPostgreSQLを加速する~クエリ処理スループット10GB/sへの挑戦~ [DB Tech Showcase Tokyo/2017]
Kohei KaiGai
 
Jpug study-postgre sql-10-pub
Toshi Harada
 
Ad

Similar to [9.5新機能]追加されたgroupbyの使い方 (20)

PPTX
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~
Miki Shimogai
 
PPTX
SQLチューニング入門 入門編
Miki Shimogai
 
PPT
20090107 Postgre Sqlチューニング(Sql編)
Hiromu Shioya
 
PDF
知って得するWebで便利なpostgre sqlの3つの機能
Soudai Sone
 
PPTX
PostgreSQL 12は ここがスゴイ! ~性能改善やpluggable storage engineなどの新機能を徹底解説~ (NTTデータ テクノ...
NTT DATA Technology & Innovation
 
PPTX
PostgreSQL14の pg_stat_statements 改善(第23回PostgreSQLアンカンファレンス@オンライン 発表資料)
NTT DATA Technology & Innovation
 
PDF
PostgreSQLによるデータ分析ことはじめ
Ohyama Masanori
 
PDF
2018年度 若手技術者向け講座 SQL概要
keki3
 
PDF
PostgreSQL13 新機能紹介
Satoshi Hirata
 
PDF
PostgreSQL13を検証してみた
Naoya Takeuchi
 
PDF
PostgreSQL18新機能紹介(db tech showcase 2025 発表資料)
NTT DATA Technology & Innovation
 
PDF
JPUGしくみ+アプリケーション勉強会(第20回)
Yoshinori Nakanishi
 
PDF
Incoming PostgreSQL 9.4 次バージョンの新機能をご紹介
Ryuichiro Munechika
 
PDF
PostgreSQL SQLチューニング入門 実践編(pgcon14j)
Satoshi Yamada
 
PDF
PostgreSQL 12の話
Masahiko Sawada
 
PDF
位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo
Yoshiyuki Asaba
 
PDF
PostgreSQL のイケてるテクニック7選
Tomoya Kawanishi
 
PDF
TPC-DSから学ぶPostgreSQLの弱点と今後の展望
Kohei KaiGai
 
PDF
PostgreSQL 9.6 新機能紹介
Masahiko Sawada
 
PPTX
押さえておきたい、PostgreSQL 13 の新機能!! (PostgreSQL Conference Japan 2020講演資料)
NTT DATA Technology & Innovation
 
PostgreSQLクエリ実行の基礎知識 ~Explainを読み解こう~
Miki Shimogai
 
SQLチューニング入門 入門編
Miki Shimogai
 
20090107 Postgre Sqlチューニング(Sql編)
Hiromu Shioya
 
知って得するWebで便利なpostgre sqlの3つの機能
Soudai Sone
 
PostgreSQL 12は ここがスゴイ! ~性能改善やpluggable storage engineなどの新機能を徹底解説~ (NTTデータ テクノ...
NTT DATA Technology & Innovation
 
PostgreSQL14の pg_stat_statements 改善(第23回PostgreSQLアンカンファレンス@オンライン 発表資料)
NTT DATA Technology & Innovation
 
PostgreSQLによるデータ分析ことはじめ
Ohyama Masanori
 
2018年度 若手技術者向け講座 SQL概要
keki3
 
PostgreSQL13 新機能紹介
Satoshi Hirata
 
PostgreSQL13を検証してみた
Naoya Takeuchi
 
PostgreSQL18新機能紹介(db tech showcase 2025 発表資料)
NTT DATA Technology & Innovation
 
JPUGしくみ+アプリケーション勉強会(第20回)
Yoshinori Nakanishi
 
Incoming PostgreSQL 9.4 次バージョンの新機能をご紹介
Ryuichiro Munechika
 
PostgreSQL SQLチューニング入門 実践編(pgcon14j)
Satoshi Yamada
 
PostgreSQL 12の話
Masahiko Sawada
 
位置情報を使ったサービス「スマポ」をPostgreSQLで作ってみた db tech showcase 2013 Tokyo
Yoshiyuki Asaba
 
PostgreSQL のイケてるテクニック7選
Tomoya Kawanishi
 
TPC-DSから学ぶPostgreSQLの弱点と今後の展望
Kohei KaiGai
 
PostgreSQL 9.6 新機能紹介
Masahiko Sawada
 
押さえておきたい、PostgreSQL 13 の新機能!! (PostgreSQL Conference Japan 2020講演資料)
NTT DATA Technology & Innovation
 
Ad

More from Kosuke Kida (8)

PDF
Jjugccc2017spring-postgres-ccc_m1
Kosuke Kida
 
PDF
Oratopostgres-hiroshima
Kosuke Kida
 
PDF
[OSC2016沖縄]商用DBからPostgreSQLへの移行入門
Kosuke Kida
 
PDF
商用DBからPostgreSQLへ まず知っておいて欲しいまとめ
Kosuke Kida
 
PDF
ランナーから見た糖質
Kosuke Kida
 
PDF
[Postgre sql9.4新機能]レプリケーション・スロットの活用
Kosuke Kida
 
PDF
まずやっとくPostgreSQLチューニング
Kosuke Kida
 
PDF
Oss x user_meeting_6_postgres
Kosuke Kida
 
Jjugccc2017spring-postgres-ccc_m1
Kosuke Kida
 
Oratopostgres-hiroshima
Kosuke Kida
 
[OSC2016沖縄]商用DBからPostgreSQLへの移行入門
Kosuke Kida
 
商用DBからPostgreSQLへ まず知っておいて欲しいまとめ
Kosuke Kida
 
ランナーから見た糖質
Kosuke Kida
 
[Postgre sql9.4新機能]レプリケーション・スロットの活用
Kosuke Kida
 
まずやっとくPostgreSQLチューニング
Kosuke Kida
 
Oss x user_meeting_6_postgres
Kosuke Kida
 

Recently uploaded (10)

PDF
20250726_Devinで変えるエンプラシステム開発の未来
Masaki Yamakawa
 
PPTX
baserCMS『カスタムコンテンツ』徹底活用術〜あなただけの管理画面を自由自在に〜
Ryuji Egashira
 
PDF
20250729_Devin-for-Enterprise
Masaki Yamakawa
 
PPTX
2025_7_25_吉祥寺_設計ナイト_ADR運用におけるデータ利活用の考え方.pptx
ssuserfcafd1
 
PDF
【学会聴講報告】CVPR2025からみるVision最先端トレンド / CVPR2025 report
Sony - Neural Network Libraries
 
PDF
VMUG Japan book vsan 20250515 CPU/Memory vSAN
Kazuhiro Sota
 
PDF
20250730_QiitaBash_LT登壇資料_PDC_Kurashina.pdf
pdckurashina
 
PDF
第三世代 ウェザーステーションキット v3 ー WSC3-L 日本語カタログ
CRI Japan, Inc.
 
PDF
MahiroYoshida_セリフに着目したキャラクタロール推定に関する基礎検討_sigcc12th2025
Matsushita Laboratory
 
PDF
TaketoFujikawa_ComicComputing12th_inKumamoto
Matsushita Laboratory
 
20250726_Devinで変えるエンプラシステム開発の未来
Masaki Yamakawa
 
baserCMS『カスタムコンテンツ』徹底活用術〜あなただけの管理画面を自由自在に〜
Ryuji Egashira
 
20250729_Devin-for-Enterprise
Masaki Yamakawa
 
2025_7_25_吉祥寺_設計ナイト_ADR運用におけるデータ利活用の考え方.pptx
ssuserfcafd1
 
【学会聴講報告】CVPR2025からみるVision最先端トレンド / CVPR2025 report
Sony - Neural Network Libraries
 
VMUG Japan book vsan 20250515 CPU/Memory vSAN
Kazuhiro Sota
 
20250730_QiitaBash_LT登壇資料_PDC_Kurashina.pdf
pdckurashina
 
第三世代 ウェザーステーションキット v3 ー WSC3-L 日本語カタログ
CRI Japan, Inc.
 
MahiroYoshida_セリフに着目したキャラクタロール推定に関する基礎検討_sigcc12th2025
Matsushita Laboratory
 
TaketoFujikawa_ComicComputing12th_inKumamoto
Matsushita Laboratory
 

[9.5新機能]追加されたgroupbyの使い方

  • 1. 第6回 PostgreSQLアンカンファレンス 1/21 第6回 PostgreSQLアンカンファレンス [9.5新機能] 追加されたGROUP BY機能の使い方 Kosuke Kida SlideShareへの公開にあたり、2015年12月12日(土)アンカンファレンス当日の発表後に いただいたコメントを元に一部項目を追加しています。 主な追記箇所  P.9  分析系の用途でDB選択時、本機能追加がどう影響するかコメント  P.10- CUBEの実行計画をより分かりやすいものに変更、スライド追加  P.20- 最後に挙げた疑問点のうち、解決の糸口になりそうな情報を発表後の質疑から追記 ※追記個所は本テキストボックスと同色の枠で記載
  • 2. 第6回 PostgreSQLアンカンファレンス 2/21 アジェンダ 9.5の新機能を勉強中のうちの一つを発表してみる ● 標準SQLへの対応 ● 良いところ ● 実用シーンを考察 ● マニュアルにないところの疑問 仕事ではPostgreSQL、Postgres Plusのプリセールス、他DBからの移行評価、環境構築、 トラブル対応などやっています。(PostgreSQLを知らない)顧客対応がほとんどの中で、 どんな情報が有益か考える中で、ベータ版時点から自分で触って、使い方、使いどころを 掴もうと試みています。(Ver9.3ぐらいから)  ・特にアンカンファレンスが開催されるようになって、新機能に対する   初めの一歩のハードルが大きく下がった  ・どういうシーンで使えるかまで考えておくと、お客様からの反応が大きい  ・分析系の用途でPostgreSQLはどこまで使えるか、という相談は最近多いので   BRINインデックスとか、集計構文とか、結構注目されてる
  • 3. 第6回 PostgreSQLアンカンファレンス 3/21 標準SQLへの対応 1クエリで複数の集計を組合せて取得 ● GROUP BY GROUPING SETS ✔ こんな売上実績データ(result表、item表、shop表をJOIN) SELECT r_date::date date,s_name,i_name,r_qt,r_qt * i_price sales FROM result JOIN item ON r_item = i_code JOIN shop ON i_shop = s_id ORDER BY r_date; r_date | s_name | i_name | r_qt | sales ------------+------------+--------------+------+-------- 2015-10-30 | Paul Smith | スラックス | 1 | 20000 2015-10-30 | Dior | シャツ | 2 | 60000 2015-10-30 | Dior | 冬ジャケット | 1 | 100000 2015-10-30 | Paul Smith | シャツ | 1 | 15000 2015-10-31 | DIESEL | ダメージB | 1 | 35000 2015-10-31 | DIESEL | ストレート | 2 | 50000 2015-10-31 | Dior | 冬ジャケット | 1 | 100000 2015-10-31 | Dior | シャツ | 1 | 30000 2015-11-01 | Paul Smith | シャツ | 3 | 45000 2015-11-02 | DIESEL | ダメージA | 1 | 30000
  • 4. 第6回 PostgreSQLアンカンファレンス 4/21 標準SQLへの対応 1クエリで複数の集計を組合せて取得 ● GROUP BY GROUPING SETS ✔ 日別の売上集計と店舗毎の売り上げ集計が欲しい SELECT r_date::date date      ,sum(r_qt * i_price) sum FROM result JOIN item ON r_item = i_code JOIN shop ON i_shop = s_id GROUP BY date ORDER BY sum DESC; date | sum ------------+-------- 2015-10-31 | 215000 2015-10-30 | 195000 2015-11-08 | 50000 2015-11-01 | 45000 2015-11-03 | 45000 2015-11-02 | 45000 2015-11-07 | 40000 2015-11-06 | 30000  : SELECT s_name shop      ,sum(r_qt * i_price) sum FROM result JOIN item ON r_item = i_code JOIN shop ON i_shop = s_id GROUP BY shop ORDER BY sum DESC; shop | sum ------------+-------- Dior | 350000 DIESEL | 195000 Paul Smith | 165000 (3 行)
  • 5. 第6回 PostgreSQLアンカンファレンス 5/21 標準SQLへの対応 1クエリで複数の集計を組合せて取得 ● GROUP BY GROUPING SETS ✔ 1クエリで店舗別、日別、総計を取得 SELECT s_name shop,r_date::date date,sum(r_qt * i_price) sum FROM result JOIN item ON r_item = i_code JOIN shop ON i_shop = s_id GROUP BY GROUPING SETS ((shop),(date),()); shop | date | sum ------------+------------+-------- DIESEL | | 195000 Dior | | 350000 Paul Smith | | 165000 | | 710000 /*総計*/ | 2015-10-30 | 195000 | 2015-10-31 | 215000 | 2015-11-01 | 45000 | 2015-11-02 | 45000 | 2015-11-03 | 45000              :
  • 6. 第6回 PostgreSQLアンカンファレンス 6/21 標準SQLへの対応 1クエリで複数の集計を組合せて取得 ● ROLLUP ✔ 1クエリで店舗-日付の組合せ、店舗別売上、総計を取得 SELECT s_name shop,r_date::date date      ,sum(r_qt * i_price) sum FROM result JOIN item ON r_item = i_code JOIN shop ON i_shop = s_id GROUP BY ROLLUP ((shop),(date)); shop | date | sum ------------+------------+-------- DIESEL | 2015-10-31 | 85000 DIESEL | 2015-11-02 | 30000 DIESEL | 2015-11-06 | 30000 DIESEL | | 195000 Dior | 2015-10-30 | 160000 Dior | 2015-10-31 | 130000 Dior | | 350000 Paul Smith | 2015-10-30 | 35000 Paul Smith | 2015-11-01 | 45000 Paul Smith | 2015-11-02 | 15000 Paul Smith | | 165000 | | 710000 (結果はスライド用にところどころ省略)
  • 7. 第6回 PostgreSQLアンカンファレンス 7/21 標準SQLへの対応 1クエリで複数の集計を組合せて取得 ● CUBE ✔ 1クエリで店舗-日付の組合せ、店舗別売上、日別売上、総計を取得 SELECT s_name shop,r_date::date date      ,sum(r_qt * i_price) sum FROM result JOIN item ON r_item = i_code JOIN shop ON i_shop = s_id GROUP BY CUBE ((shop),(date)); shop | date | sum ------------+------------+-------- DIESEL | 2015-10-31 | 85000 DIESEL | 2015-11-02 | 30000 DIESEL | | 195000 Dior | 2015-10-30 | 160000 Dior | 2015-11-08 | 30000 Dior | | 350000 Paul Smith | 2015-10-30 | 35000 Paul Smith | 2015-11-01 | 45000 Paul Smith | 2015-11-02 | 15000 Paul Smith | 2015-11-08 | 20000 Paul Smith | | 165000 | | 710000 | 2015-10-30 | 195000 | 2015-10-31 | 215000 | 2015-11-08 | 50000 (結果はスライド用にところどころ省略)
  • 8. 第6回 PostgreSQLアンカンファレンス 8/21 良いところ(教科書的な) 1クエリで結果を取得できるので ● APとDBのやりとりの回数を削減 日別集計 店舗別集計 総計 あらゆる組合せ
  • 9. 第6回 PostgreSQLアンカンファレンス 9/21 良いところ(教科書的な) 1クエリで結果を取得できるので ● SeqScanの回数を削減 日別集計 30分 店舗別集計 30分 総計 30分 あらゆる組合せ 1時間 分析用途で現状PostgreSQLが どの程度使えるのか? という問いに対して、回答は、 今のところ、リアルタイム性を どこまで求めるかだと思う。 --- 左記に近い実際にあった例だと、 1日1回、オンライン系のシステム から実績データを取込み、夜間 バッチで加工・集計して、複数の Mビューで保持しとく使い方。 夜間のうちに完了するかどうかが DB選定の肝になっていた。 構文が追加された事による 実行計画の効率化が採用可否の 分岐点になりそうな予感。 --- ※ちなみにOracle EEで限界まで チューニングして同じことをやると 1秒で結果が得られるとか、 それぐらいのスピード感になりそうな話。 「こ、これがリアルタイムか・・・ぐぬぬ」
  • 10. 第6回 PostgreSQLアンカンファレンス 10/21 実用シーンを考察 実行計画はどうなるか ● CUBEの実行計画を確認する               ✔ このテーブルに対して従来の各項目別にGROUP BYすると – 全件のカウント 306.755 ms – アイテム種別カウント 718.326 ms – 売上日別カウント 596.246 ms – 売上店舗別カウント 609.198 ms  計2200 msぐらい ✔ CUBEでは加えて「日別-アイテム別」や「日別-店舗別」等、全組合せ集計結果を取得 -- CUBEのみの実行計画を見たい。 -- JOINの影響をなくすため、類似のデータを単一のテーブルで用意 -- 100万件超えるまで、適当にINSERT INTO huge SELECT * FROM result JOIN item・・・ postgres=# SELECT count(*) FROM huge; count --------- 1310720 postgres=# show work_mem; work_mem ---------- 4MB   -- デフォルト
  • 11. 第6回 PostgreSQLアンカンファレンス 11/21 実用シーンを考察 実行計画はどうなるか ● SeqScanの回数を削減 ✔ ただし、ソートが激増してDISKソートになると劇遅(2.2秒→7.8秒) postgres=# EXPLAIN ANALYZE postgres-# SELECT sales_date::date,shop,kind,count(*) FROM huge postgres-# GROUP BY CUBE ((sales_date::date),(shop),(kind)); QUERY PLAN -------------------------------------------------------------------------------------------------------------------- GroupAggregate (cost=194723.79..566418.36 rows=336 width=26) (actual time=2671.543..7775.091 rows=69 loops=1) Group Key: ((sales_date)::date), shop, kind Group Key: ((sales_date)::date), shop Group Key: ((sales_date)::date) Group Key: () Sort Key: kind, ((sales_date)::date) Group Key: kind, ((sales_date)::date) Group Key: kind Sort Key: shop, kind Group Key: shop, kind Group Key: shop -> Sort (cost=194723.79..198000.59 rows=1310720 width=26) (actual time=2501.926..3181.656 rows=1310720 loops=1) Sort Key: ((sales_date)::date), shop, kind Sort Method: external merge Disk: 42216kB -> Seq Scan on huge (cost=0.00..30182.00 rows=1310720 width=26) (actual time=0.023..290.534 rows=1310720 loops=1) Planning time: 0.141 ms Execution time: 7788.108 ms (17 行)
  • 12. 第6回 PostgreSQLアンカンファレンス 12/21 実用シーンを考察 実行計画はどうなるか ● SeqScanの回数を削減 ✔ ただし、ソートが激増してDISKソートになると劇遅 ✔ work_memの増加で対処(2.2秒→7.8秒→3.0秒) postgres=# set work_mem to '200MB'; SET postgres=# EXPLAIN ANALYZE SELECT sales_date::date,shop,kind,count(*) FROM huge GROUP BY CUBE ((sales_date::date),(shop),(kind)); QUERY PLAN -------------------------------------------------------------------------------------------------------------------- GroupAggregate (cost=163363.79..472338.36 rows=336 width=26) (actual time=1041.637..2986.535 rows=69 loops=1) Group Key: ((sales_date)::date), shop, kind Group Key: ((sales_date)::date), shop Group Key: ((sales_date)::date) Group Key: () Sort Key: kind, ((sales_date)::date) Group Key: kind, ((sales_date)::date) Group Key: kind Sort Key: shop, kind Group Key: shop, kind Group Key: shop -> Sort (cost=163363.79..166640.59 rows=1310720 width=26) (actual time=978.680..1147.774 rows=1310720 loops=1) Sort Key: ((sales_date)::date), shop, kind Sort Method: quicksort Memory: 149662kB -> Seq Scan on huge (cost=0.00..30182.00 rows=1310720 width=26) (actual time=0.030..316.498 rows=1310720 loops=1) Planning time: 0.238 ms Execution time: 3006.193 ms (17 行)
  • 13. 第6回 PostgreSQLアンカンファレンス 13/21 実用シーンを考察 実行計画はどうなるか ● CUBEの実行計画を確認する ✔ このテーブルに対して従来の各項目別にGROUP BYすると – 全件のカウント 306.755 ms – アイテム種別カウント 718.326 ms – 売上日別カウント 596.246 ms – 売上店舗別カウント 609.198 ms  計2200 msぐらい ✔ CUBEでは加えて「日別-アイテム別」や「日別-店舗別」等、全組合せ集計結果を取得 – 全件のカウント – アイテム種別カウント – 売上日別カウント – 売上店舗別カウント – 日別-アイテム別カウント – 日別-店舗別カウント – アイテム別ー店舗別カウント – 日別ーアイテム別ー店舗別カウント   計3000 ms ぐらい
  • 14. 第6回 PostgreSQLアンカンファレンス 14/21 実用シーンを考察 クロス集計までDBで行う ● クロス集計 ✔ 何かのアイテムに関する街頭調査結果みたいなイメージ ✔ それぞれの枠に対してクエリを書いてデータを取得する必要があった ✔ CUBEならこれを1クエリで取得できているので、 あとは「行列変換して表示」できればOKなのだが。 性別 男 女 合計 年代 ~20代 それ以上 ~20代 それ以上 -- アイテムA 10人 10人 80人 100人 200人 アイテムB 20人 10人 50人 80人 160人 アイテムC 30人 10人 50人 50人 140人 合計 60人 30人 180人 230人 500人
  • 15. 第6回 PostgreSQLアンカンファレンス 15/21 実用シーンを考察 1クエリで複数の集計を組合せて取得 ● CUBEでは、クロス集計表を埋める結果はすべて取得済み ✔ 1クエリで店舗-日付の組合せ、店舗別売上、日別売上、総計を取得 SELECT s_name shop,r_date::date date      ,sum(r_qt * i_price) sum FROM result JOIN item ON r_item = i_code JOIN shop ON i_shop = s_id GROUP BY CUBE ((shop),(date)); shop | date | sum ------------+------------+-------- DIESEL | 2015-10-31 | 85000 DIESEL | 2015-11-02 | 30000 DIESEL | | 195000 Dior | 2015-10-30 | 160000 Dior | 2015-11-08 | 30000 Dior | | 350000 Paul Smith | 2015-10-30 | 35000 Paul Smith | 2015-11-01 | 45000 Paul Smith | 2015-11-02 | 15000 Paul Smith | 2015-11-08 | 20000 Paul Smith | | 165000 | | 710000 | 2015-10-30 | 195000 | 2015-10-31 | 215000 | 2015-11-08 | 50000 (結果はスライド用にところどころ省略) shop | date | sum ------------+------------+-------- DIESEL | 2015-10-31 | 85000 DIESEL | 2015-11-02 | 30000 DIESEL | | 195000 Dior | 2015-10-30 | 160000 Dior | 2015-11-08 | 30000 Dior | | 350000 Paul Smith | 2015-10-30 | 35000 Paul Smith | 2015-11-01 | 45000 Paul Smith | 2015-11-02 | 15000 Paul Smith | 2015-11-08 | 20000 Paul Smith | | 165000 | | 710000 | 2015-10-30 | 195000 | 2015-10-31 | 215000 | 2015-11-08 | 50000 (結果はスライド用にところどころ省略)
  • 16. 第6回 PostgreSQLアンカンファレンス 16/21 実用シーンを考察 クロス集計までDBで完結する ● クロス集計 ✔ tablefuncエクステンションでクロス集計 # rpm -ivh postgresql95-contrib-9.5-beta1_1PGDG.el6.x86_64.rpm # psql postgres=# create extension tablefunc; CREATE EXTENSION
  • 17. 第6回 PostgreSQLアンカンファレンス 17/21 実用シーンを考察 クロス集計までDBで完結する ● クロス集計 ✔ tablefuncエクステンションでクロス集計 --CUBE結果をMViewに保存(tablefuncの構文をシンプルにしたいので今回はコレで。) CREATE MATERIALIZED VIEW mv_cube AS SELECT sales_date::date,shop,kind,count(*) FROM result GROUP BY CUBE ((sales_date::date),(shop),(kind)); --crosstab関数をかませて結果を整形 SELECT * FROM crosstab(' SELECT date,COALESCE(shop,''null''),sum FROM mv_cube     --整形したいクエリ ORDER BY date ',' SELECT DISTINCT COALESCE(shop,''null'') shop FROM mv_cube --2番目の引数は ORDER BY shop NULLS LAST --結果の列名に対応 ') AS sales ( date date ,"DIESEL" numeric ,"Dior" numeric ,"Paul Smith" numeric ,"daily sum" numeric );
  • 18. 第6回 PostgreSQLアンカンファレンス 18/21 date | DIESEL | Dior | Paul Smith | daily sum ------------+--------+--------+------------+----------- 2015-10-30 | | 160000 | 35000 | 195000 2015-10-31 | 85000 | 130000 | | 215000 2015-11-01 | | | 45000 | 45000 2015-11-02 | 30000 | | 15000 | 45000 2015-11-03 | 25000 | | 20000 | 45000 2015-11-04 | | 30000 | | 30000 2015-11-05 | | | 15000 | 15000 2015-11-06 | 30000 | | | 30000 2015-11-07 | 25000 | | 15000 | 40000 2015-11-08 | | 30000 | 20000 | 50000 | 195000 | 350000 | 165000 | 710000 (11 行) 実用シーンを考察 クロス集計までDBで完結する ● クロス集計 ✔ tablefuncエクステンションでクロス集計
  • 19. 第6回 PostgreSQLアンカンファレンス 19/21 date | DIESEL | Dior | Paul Smith | daily sum ------------+--------+--------+------------+----------- 2015-10-30 | | 160000 | 35000 | 195000 2015-10-31 | 85000 | 130000 | | 215000 2015-11-01 | | | 45000 | 45000 2015-11-02 | 30000 | | 15000 | 45000 2015-11-03 | 25000 | | 20000 | 45000 2015-11-04 | | 30000 | | 30000 2015-11-05 | | | 15000 | 15000 2015-11-06 | 30000 | | | 30000 2015-11-07 | 25000 | | 15000 | 40000 2015-11-08 | | 30000 | 20000 | 50000 | 195000 | 350000 | 165000 | 710000 (11 行) 実用シーンを考察 クロス集計までDBで完結する ● クロス集計 ✔ tablefuncエクステンションでクロス集計 date | DIESEL | Dior | Paul Smith | daily sum ------------+--------+--------+------------+----------- 2015-10-30 | | 160000 | 35000 | 195000 2015-10-31 | 85000 | 130000 | | 215000 2015-11-01 | | | 45000 | 45000 2015-11-02 | 30000 | | 15000 | 45000 2015-11-03 | 25000 | | 20000 | 45000 2015-11-04 | | 30000 | | 30000 2015-11-05 | | | 15000 | 15000 2015-11-06 | 30000 | | | 30000 2015-11-07 | 25000 | | 15000 | 40000 2015-11-08 | | 30000 | 20000 | 50000 | 195000 | 350000 | 165000 | 710000 (11 行)
  • 20. 第6回 PostgreSQLアンカンファレンス 20/21 マニュアルで見つけられなかった疑問 grouping関数の存在と役割 ● 標準SQLやOracleの構文を見ていると登場するGROUPING関数 ✔ 指定してみたらPostgreSQL 9.5でも使えた ✔ しかしマニュアルに無く、pg_procなどからも定義が探せない SELECT grouping(s_name) AS g1 ,grouping(r_date::date) AS g2 ,grouping(s_name,r_date::date) AS gX ,s_name shop,r_date::date date,sum(r_qt * i_price) sum FROM result JOIN item ON r_item = i_code JOIN shop ON i_shop = s_id GROUP BY GROUPING SETS ((shop),(date),()); g1 | g2 | gx | shop | date | sum ----+----+----+------------+------------+-------- 0 | 1 | 1 | DIESEL | | 195000 0 | 1 | 1 | Dior | | 350000 0 | 1 | 1 | Paul Smith | | 165000 1 | 1 | 3 | | | 710000 1 | 0 | 2 | | 2015-10-30 | 195000 1 | 0 | 2 | | 2015-10-31 | 215000 この実行例が意味をあらわしている? 本当にnullだったか、グルーピングされた結果かどうか gXの3は、2進数の11?項目が増えたら?
  • 21. 第6回 PostgreSQLアンカンファレンス 21/21 マニュアルで見つけられなかった疑問 grouping関数の存在と役割 ● 標準SQLやOracleの構文を見ていると登場するGROUPING関数 ✔ 指定してみたらPostgreSQL 9.5でも使えた ✔ しかしマニュアルに無く、pg_procなどからも定義が探せない – パーサーのソースコード中にそれらしき定義がありそう – http://doxygen.postgresql.org/で検索してみたら、確かにそんな感じ groupingは関数ではなく、構造体?の扱い パーサーのコードの中にありそう 詳細は後日確認します!