10. WITH ( )
WITH, WITH RECURSIVE
ID
=# TABLE tree;
id | parent 1
----+--------
1 |
2 | 1 2 3 self-join
3 | 1
4 | 3 4
...
=# WITH RECURSIVE r AS (
SELECT * FROM tree WHERE id = 1
UNION ALL
SELECT tree.* FROM tree, r WHERE tree.parent = r.id
)
SELECT * FROM r ORDER BY id;
id | parent
----+--------
1 |
2 | 1
3 | 1
4 | 3
(4 rows)
10
11. WITH ( ):
ML (!?)
WITH RECURSIVE Z(IX, IY, CX, CY, X, Y, I) AS (
SELECT IX, IY, X::float, Y::float, X::float, Y::float, 0
FROM (SELECT -2.2 + 0.031 * i, i
FROM generate_series(0, 101) AS i) AS xgen(x, ix),
(SELECT -1.5 + 0.031 * i, i
FROM generate_series(0, 101) AS i) AS ygen(y, iy)
UNION ALL
SELECT IX, IY, CX, CY,
X * X - Y * Y + CX AS X, Y * X * 2 + CY, I + 1
FROM Z
WHERE X * X + Y * Y < 16::float
AND I < 100
)
SELECT array_to_string(array_agg(substring(' .,,,-----++++%%%%@@@@#### ',
least(greatest(I,1),27), 1)),'')
FROM (
SELECT IX, IY, max(I) AS I
FROM Z
GROUP BY IY, IX
ORDER BY IY, IX
) AS ZT
GROUP BY IY
Q. ?
ORDER BY IY;
11
13. WITH (vs. CONNECT BY)
Oracle CONNECT BY / contrib/tablefunc connectby()
Oracle : CONNECT BY
SELECT level, empno, mgr, ename, job
FROM emp
START WITH mgr IS NULL
CONNECT BY PRIOR empno = mgr
PostgreSQL ~8.3 : connectby()
SELECT t.level, e.empno, e.mgr, e.ename, e.job
FROM emp e, (SELECT * FROM
connectby('emp', 'empno', 'mgr', 'mgr', 7839, 0, '~')
AS cb(empno int, mgr int, level int, branch text, pos int)) t
WHERE e.empno = t.empno;
PostgreSQL 8.4 : WITH RECURSIVE SQL
WITH RECURSIVE r AS (
SELECT 1 AS level, * FROM emp WHERE mgr IS NULL
UNION ALL
SELECT r.level + 1, emp.* FROM emp, r WHERE r.empno = emp.mgr
)
SELECT * FROM r;
13
14. Window :
GROUP BY
(...) OVER (PARTITION BY ...)
(...) OVER (ORDER BY ...)
row_number()
rank() ( )
dense_rank() ( )
percent_rank()
(% )
cume_dist()
ntile(N) (1..N )
self-join
lag(value, ...)
lead(value, ...)
first_value(value)
14
15. Window :
SELECT row_number() OVER (), *
FROM (SELECT * FROM tbl ORDER BY sortkey) AS t;
10%
SELECT ... FROM
(SELECT *, cume_dist() OVER (ORDER BY i) AS rank
FROM tbl) AS t
WHERE rank <= 0.1; LIMIT 10%
LIMIT count(*) / 10
SELECT id, , ,
rank() OVER (PARTITION BY ORDER BY )
FROM tbl;
15
17. WITH + Window (2/4)
locktag()
CREATE FUNCTION locktag(pg_catalog.pg_locks) RETURNS text AS
$$
SELECT $1.locktype || ' ' ||
CASE $1.locktype
WHEN 'relation' THEN $1.database || ' ' || $1.relation
WHEN 'extend' THEN $1.database || ' ' || $1.relation
WHEN 'page' THEN $1.database || ' ' || $1.relation || ' ' || $1.page
WHEN 'tuple' THEN $1.database || ' ' || $1.relation || ' ' || $1.page
|| ' ' || $1.tuple
WHEN 'transactionid' THEN $1.transactionid::text
WHEN 'virtualxid' THEN $1.virtualxid
-- FIXME: for object, userlock and advisory
END
$$
LANGUAGE sql IMMUTABLE STRICT;
17
18. WITH + Window (3/4)
pg_lock_chain
row_number()
CREATE VIEW pg_lock_chain AS
WITH RECURSIVE r AS (
SELECT *, locktag(pg_locks),
row_number() OVER () AS chain,
1 AS level
FROM pg_locks WHERE NOT granted
UNION ALL
SELECT s.*, locktag(s), r.chain, r.level + 1
FROM r, pg_locks s
WHERE (locktag(s) = r.locktag AND s.granted AND
NOT r.granted AND s.pid <> r.pid)
OR (s.pid = r.pid AND NOT s.granted AND r.granted)
)
SELECT * FROM r; locktag
18
24. SQL :
postgresql.conf
shared_preload_libraries = 'pg_stat_statements'
prepared
pgbench (Prepared Statement)
$ pgbench -c10 -t300 -M prepared
query mode: prepared
number of transactions actually processed: 3000/3000
SQL
=# SELECT query, calls, total_time, rows FROM pg_stat_statements ORDER BY total_time DESC LIMIT 3;
query | calls | total_time | rows
--------------------------------------------------------------+-------+-------------------+------
UPDATE branches SET bbalance = bbalance + $1 WHERE bid = $2; | 3000 | 35.9654100452473 | 3000
UPDATE tellers SET tbalance = tbalance + $1 WHERE tid = $2; | 3000 | 34.7969816235719 | 3000
UPDATE accounts SET abalance = abalance + $1 WHERE aid = $2; | 3000 | 0.660384690059746 | 3000
(3 rows)
SQL
◎
◎ 3%
× HTML
24
25. Visibility Map : VACUUM
PostgreSQL VACUUM ?
ID ID
001 A 10 001 A 10
002 B 8
UPDATE 003 C 20 003 C 20 VACUUM
002 B 7 002 B 7
8.4 VACUUM
Visibility Map
VACUUM +
Free Space Map
8.3 HOT ?
HOT =
Visibility Map =
25
27. SQL
SQL
id value 1 (2392) 2 (pid=1956)
BEGIN; BEGIN;
1 A
UPDATE tbl SET value = 'AA'
2 B WHERE id = 1; UPDATE tbl SET value = 'BB'
WHERE id = 2;
UPDATE tbl SET value = 'BBB'
WHERE id = 2;
UPDATE tbl SET value = 'AAA'
WHERE id = 1;
ERROR: deadlock detected
DETAIL:
Process 1956 waits for ShareLock on transaction 8214; blocked by process 2392.
Process 2392 waits for ShareLock on transaction 8215; blocked by process 1956.
Process 1956: UPDATE tbl SET value = 'AAA' WHERE id = 1;
Process 2392: UPDATE tbl SET value = 'BBB' WHERE id = 2;
27
34. ToDo ( )
http://wiki.postgresql.org/wiki/Todo
PostgreSQL 8.4 Development Plan ( )
http://wiki.postgresql.org/wiki/PostgreSQL_8.4_Dev
elopment_Plan
Waiting for 8.4 ( blog)
http://www.depesz.com/
34