[db tech showcase Tokyo 2014] D21: Postgres Plus Advanced Serverはここが使える&9.4新機...Insight Technology, Inc.
?
日本でも徐々に浸透してきたPostgres Plus Advanced Server (PPAS)。PPASが備えている実用的な機能を2014年末にリリース予定の最新版9.4の新機能を交えて、コミュニティ版PostgreSQLと比較しながら解説します。
特に性能面で大きな向上をうたっているパーティショニング機能については実際に検証した結果を紹介します。
17. データの偏りを考える
?まずは索引の有無を意識
?SQLとテーブル定義
?インデックスが無いが、
テーブルのほぼ全行を取得したいため、問題なし
Japan PostgreSQL User's Group 17
1万人中、95%の人がアクティブなstate列
SELECT
u_id,u_regdate
FROM m_user
WHERE u_state = active
ORDER BY u_regdate ASC;
/* m_user表の定義 */
----------- -------------
u_id integer
u_name text
u_lastname text
u_firstname text
u_state integer
u_tel text
u_regdate timestamp
index : m_user_pk (u_id)
【ケーススタディ】
20. 実行計画を確認する
?様々なアクセス方法のうち、どの方法が選択されたか確認
Japan PostgreSQL User's Group 20
PostgreSQLはEXPLAIN文で簡単に実行計画を確認可能
【ハイレベル】
postgres=# EXPLAIN
postgres-# SELECT u_id,u_regdate FROM m_user
postgres-# WHERE u_state = 1
postgres-# ORDER BY u_regdate ASC;
QUERY PLAN
--------------------------------------------------------------
Sort (cost=15.88..15.89 rows=2 width=12)
Sort Key: u_regdate
-> Seq Scan on m_user (cost=0.00..15.88 rows=2 width=12)
Filter: (u_state = 1)
EXPLAIN
SELECT
u_id,u_regdate
FROM m_user
WHERE u_state = active
ORDER BY u_regdate ASC;
postgres=# CREATE INDEX u_idx ON m_user(u_regdate);
/* 上記のクエリを再実行すると実行計画が変化 */
QUERY PLAN
----------------------------------------------------------------------
Index Scan using u_idx on m_user (cost=0.15..52.37 rows=2 width=12)
Filter: (u_state = 1)
22. 結合の構文が難しい?
?テーブルから1件の結果を取り出す
?とあるサービスの利用者が自身の投稿一覧を見る画面
?取り出したい結果は?
?結果を考えた後、結合の条件を
考える
Japan PostgreSQL User's Group 22
SELECT文の書き方2 結合の時も考え方は同じ
ユーザーID xxxx の投稿一覧
表示名、記事タイトル
/* article表の定義 */
----------- -------------
a_id integer
userid integer
a_title text
a_regdate timestamp
a_startdate timestamp
a_enddate timestamp
index : article_pk (a_id)
SELECT
u.u_name,a.a_title
FROM article a
INNER JOIN m_user u
ON u.u_id = a.userid
WHERE u.u_id = XXXXX;
23. 内部結合
?内部結合(一般的な結合)はINNER JOINを用いる
Japan PostgreSQL User's Group
両者に共通する列から、値が一致する行を突き合わせる
SELECT
u.u_name,a.a_title
FROM article a
INNER JOIN m_user u
ON u.u_id = a.userid;
u.u_id = a.userid
?m_user表とarticle表の共通列は著者
?すべての記事には著者がいる
?しかし記事を書いていない著者もいる
記事id
1
2
3
著者id
10
10
20
著者id
10
10
20
4 30 30
5 10 10
著者
A
A
B
C
A
article
23
24. 外部結合
?外部結合はLEFT(RIGHT)OUTER JOINを用いる
Japan PostgreSQL User's Group
両者に共通する列から、値が一致する行を突き合わせる
SELECT
u.u_name,a.a_title
FROM article a
RIGHT OUTER JOIN m_user u
ON u.u_id = a.userid;
u.u_id = a.userid
?m_user表とarticle表の共通列は著者
?すべての記事には著者がいる
?しかし記事を書いていない著者もいる
記事id
1
2
3
著者id
10
10
20
著者id
10
10
20
4 30 30
5 10 10
A
A
B
C
A
著者
40 D
50 E
article
24
25. 索引を利用した結合
?同じ表を繰り返し検索するNested Loop Join
Japan PostgreSQL User's Group 25
索引は結合の時こそ効果絶大
/* article表の定義 */
----------- -------------
a_id integer
userid integer
a_title text
a_regdate timestamp
a_startdate timestamp
a_enddate timestamp
index : article_pk (a_id)
userid_idx (userid)
/* m_user表の定義 */
----------- -------------
u_id integer
u_name text
u_lastname text
u_firstname text
u_state integer
u_tel text
u_regdate timestamp
index : m_user_pk (u_id)
ユーザ数 1万人
記事件数 30万件
(一人当たり平均30件 )
30. IN句の後のサブクエリ
?IN句の後のサブクエリは結合条件による比較と同じ
Japan PostgreSQL User's Group 30
結合と同じ考え方だが、複雑な条件を書ける
article
SELECT
u.u_name,a.a_title
FROM article a
INNER JOIN m_user u
ON u.u_id = a.userid;
u.u_id = a.userid
?m_user表とarticle表の共通列は著者
?すべての記事には著者がいる
?しかし記事を書いていない著者もいる
SELECT
u.u_name,a.a_title
FROM article a
WHERE a_userid IN (SELECT u_id
FROM m_user
WHERE ???)
【参考】