create schema srf_fusion;
set search_path to srf_fusion;
set enable_expr_fusion = on;
show enable_expr_fusion;
enable_expr_fusion
--------------------
on
(1 row)
create table empsalary (id int, depname text, empno int, salary int);
INSERT INTO empsalary (id, depname, empno, salary) VALUES
(1,'develop',11,5200), (2, 'develop',7,4200),
(3, 'personnel', 9, 4500), (4, 'personnel', 8, 6000),
(5, 'sales', 10, 5300) , (6, 'sales', 18, 6200);
explain (costs off, verbose)
SELECT generate_series(1, id), depname, empno, salary, rank() OVER (PARTITION BY depname ORDER BY salary DESC) FROM empsalary;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------
ProjectSet
Output: generate_series(1, id), depname, empno, salary, (rank() OVER (PARTITION BY depname ORDER BY salary USING = NULLS LAST))
-> WindowAgg
Output: id, depname, empno, salary, rank() OVER (PARTITION BY depname ORDER BY salary USING = NULLS LAST)
-> Sort
Output: depname, salary, id, empno
Sort Key: empsalary.depname, empsalary.salary DESC
-> Seq Scan on srf_fusion.empsalary
Output: depname, salary, id, empno
(9 rows)
SELECT generate_series(1, id), depname, empno, salary, rank() OVER (PARTITION BY depname ORDER BY salary DESC) FROM empsalary;
generate_series | depname | empno | salary | rank
-----------------+-----------+-------+--------+------
1 | develop | 11 | 5200 | 1
1 | develop | 7 | 4200 | 2
2 | develop | 7 | 4200 | 2
1 | personnel | 8 | 6000 | 1
2 | personnel | 8 | 6000 | 1
3 | personnel | 8 | 6000 | 1
4 | personnel | 8 | 6000 | 1
1 | personnel | 9 | 4500 | 2
2 | personnel | 9 | 4500 | 2
3 | personnel | 9 | 4500 | 2
1 | sales | 18 | 6200 | 1
2 | sales | 18 | 6200 | 1
3 | sales | 18 | 6200 | 1
4 | sales | 18 | 6200 | 1
5 | sales | 18 | 6200 | 1
6 | sales | 18 | 6200 | 1
1 | sales | 10 | 5300 | 2
2 | sales | 10 | 5300 | 2
3 | sales | 10 | 5300 | 2
4 | sales | 10 | 5300 | 2
5 | sales | 10 | 5300 | 2
(21 rows)
explain (costs off, verbose)
SELECT generate_series(id, generate_series(1, 2)), depname, empno, salary, rank() OVER (PARTITION BY depname ORDER BY salary DESC) FROM empsalary;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------
ProjectSet
Output: generate_series(id, (generate_series(1, 2))), depname, empno, salary, (rank() OVER (PARTITION BY depname ORDER BY salary USING = NULLS LAST))
-> ProjectSet
Output: generate_series(1, 2), id, depname, empno, salary, (rank() OVER (PARTITION BY depname ORDER BY salary USING = NULLS LAST))
-> WindowAgg
Output: id, depname, empno, salary, rank() OVER (PARTITION BY depname ORDER BY salary USING = NULLS LAST)
-> Sort
Output: depname, salary, id, empno
Sort Key: empsalary.depname, empsalary.salary DESC
-> Seq Scan on srf_fusion.empsalary
Output: depname, salary, id, empno
(11 rows)
SELECT generate_series(id, generate_series(1, 2)), depname, empno, salary, rank() OVER (PARTITION BY depname ORDER BY salary DESC) FROM empsalary;
generate_series | depname | empno | salary | rank
-----------------+---------+-------+--------+------
1 | develop | 11 | 5200 | 1
1 | develop | 11 | 5200 | 1
2 | develop | 11 | 5200 | 1
2 | develop | 7 | 4200 | 2
(4 rows)
explain (costs off, verbose)
SELECT id, generate_series(1, id), salary, sum(salary) OVER () FROM empsalary;
QUERY PLAN
---------------------------------------------------------------------
ProjectSet
Output: id, generate_series(1, id), salary, (sum(salary) OVER ())
-> WindowAgg
Output: id, salary, sum(salary) OVER ()
-> Seq Scan on srf_fusion.empsalary
Output: id, salary
(6 rows)
SELECT id, generate_series(1, id), salary, sum(salary) OVER () FROM empsalary;
id | generate_series | salary | sum
----+-----------------+--------+-------
1 | 1 | 5200 | 31400
2 | 1 | 4200 | 31400
2 | 2 | 4200 | 31400
3 | 1 | 4500 | 31400
3 | 2 | 4500 | 31400
3 | 3 | 4500 | 31400
4 | 1 | 6000 | 31400
4 | 2 | 6000 | 31400
4 | 3 | 6000 | 31400
4 | 4 | 6000 | 31400
5 | 1 | 5300 | 31400
5 | 2 | 5300 | 31400
5 | 3 | 5300 | 31400
5 | 4 | 5300 | 31400
5 | 5 | 5300 | 31400
6 | 1 | 6200 | 31400
6 | 2 | 6200 | 31400
6 | 3 | 6200 | 31400
6 | 4 | 6200 | 31400
6 | 5 | 6200 | 31400
6 | 6 | 6200 | 31400
(21 rows)
explain (costs off, verbose)
SELECT id, generate_series(1, id), salary, sum(salary) OVER (ORDER BY salary) FROM empsalary;
QUERY PLAN
-------------------------------------------------------------------------------------------------------
ProjectSet
Output: id, generate_series(1, id), salary, (sum(salary) OVER (ORDER BY salary USING = NULLS LAST))
-> WindowAgg
Output: id, salary, sum(salary) OVER (ORDER BY salary USING = NULLS LAST)
-> Sort
Output: salary, id
Sort Key: empsalary.salary
-> Seq Scan on srf_fusion.empsalary
Output: salary, id
(9 rows)
SELECT id, generate_series(1, id), salary, sum(salary) OVER (ORDER BY salary) FROM empsalary;
id | generate_series | salary | sum
----+-----------------+--------+-------
2 | 1 | 4200 | 4200
2 | 2 | 4200 | 4200
3 | 1 | 4500 | 8700
3 | 2 | 4500 | 8700
3 | 3 | 4500 | 8700
1 | 1 | 5200 | 13900
5 | 1 | 5300 | 19200
5 | 2 | 5300 | 19200
5 | 3 | 5300 | 19200
5 | 4 | 5300 | 19200
5 | 5 | 5300 | 19200
4 | 1 | 6000 | 25200
4 | 2 | 6000 | 25200
4 | 3 | 6000 | 25200
4 | 4 | 6000 | 25200
6 | 1 | 6200 | 31400
6 | 2 | 6200 | 31400
6 | 3 | 6200 | 31400
6 | 4 | 6200 | 31400
6 | 5 | 6200 | 31400
6 | 6 | 6200 | 31400
(21 rows)
explain (costs off, verbose)
SELECT generate_series(1,id), sum(salary) OVER w, avg(salary) OVER w
FROM empsalary
WINDOW w AS (PARTITION BY depname ORDER BY salary DESC);
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ProjectSet
Output: generate_series(1, id), (sum(salary) OVER (PARTITION BY depname ORDER BY salary USING = NULLS LAST)), (avg(salary) OVER (PARTITION BY depname ORDER BY salary USING = NULLS LAST)), salary, depname
-> WindowAgg
Output: id, sum(salary) OVER (PARTITION BY depname ORDER BY salary USING = NULLS LAST), avg(salary) OVER (PARTITION BY depname ORDER BY salary USING = NULLS LAST), salary, depname
-> Sort
Output: salary, depname, id
Sort Key: empsalary.depname, empsalary.salary DESC
-> Seq Scan on srf_fusion.empsalary
Output: salary, depname, id
(9 rows)
SELECT generate_series(1,id), sum(salary) OVER w, avg(salary) OVER w
FROM empsalary
WINDOW w AS (PARTITION BY depname ORDER BY salary DESC);
generate_series | sum | avg
-----------------+-------+-----------------------
1 | 5200 | 5200.0000000000000000
1 | 9400 | 4700.0000000000000000
2 | 9400 | 4700.0000000000000000
1 | 6000 | 6000.0000000000000000
2 | 6000 | 6000.0000000000000000
3 | 6000 | 6000.0000000000000000
4 | 6000 | 6000.0000000000000000
1 | 10500 | 5250.0000000000000000
2 | 10500 | 5250.0000000000000000
3 | 10500 | 5250.0000000000000000
1 | 6200 | 6200.0000000000000000
2 | 6200 | 6200.0000000000000000
3 | 6200 | 6200.0000000000000000
4 | 6200 | 6200.0000000000000000
5 | 6200 | 6200.0000000000000000
6 | 6200 | 6200.0000000000000000
1 | 11500 | 5750.0000000000000000
2 | 11500 | 5750.0000000000000000
3 | 11500 | 5750.0000000000000000
4 | 11500 | 5750.0000000000000000
5 | 11500 | 5750.0000000000000000
(21 rows)
-- window + sort
explain (costs off, verbose)
SELECT id, generate_series(1, id) as g, salary, sum(salary) OVER (ORDER BY salary) FROM empsalary order by g;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------
Sort
Output: id, (generate_series(1, id)), salary, (sum(salary) OVER (ORDER BY salary USING = NULLS LAST))
Sort Key: (generate_series(1, empsalary.id))
-> ProjectSet
Output: id, generate_series(1, id), salary, (sum(salary) OVER (ORDER BY salary USING = NULLS LAST))
-> WindowAgg
Output: id, salary, sum(salary) OVER (ORDER BY salary USING = NULLS LAST)
-> Sort
Output: salary, id
Sort Key: empsalary.salary
-> Seq Scan on srf_fusion.empsalary
Output: salary, id
(12 rows)
SELECT id, generate_series(1, id) as g, salary, sum(salary) OVER (ORDER BY salary) FROM empsalary order by g;
id | g | salary | sum
----+---+--------+-------
6 | 1 | 6200 | 31400
1 | 1 | 5200 | 13900
5 | 1 | 5300 | 19200
2 | 1 | 4200 | 4200
4 | 1 | 6000 | 25200
3 | 1 | 4500 | 8700
4 | 2 | 6000 | 25200
5 | 2 | 5300 | 19200
2 | 2 | 4200 | 4200
6 | 2 | 6200 | 31400
3 | 2 | 4500 | 8700
6 | 3 | 6200 | 31400
5 | 3 | 5300 | 19200
4 | 3 | 6000 | 25200
3 | 3 | 4500 | 8700
5 | 4 | 5300 | 19200
6 | 4 | 6200 | 31400
4 | 4 | 6000 | 25200
5 | 5 | 5300 | 19200
6 | 5 | 6200 | 31400
6 | 6 | 6200 | 31400
(21 rows)
drop table empsalary;
create table tbl_1k(id bigint, v1 numeric, v2 numeric);
insert into tbl_1k select generate_series(1, 1000), (RANDOM() * 67)::int::numeric, (RANDOM() * 77)::int::numeric;
analyze tbl_1k;
set enable_hashagg=off;
explain (costs off, verbose)
select sum(id), v1,v2,generate_series(1,v1) as g1 from tbl_1k group by v1,v2 order by sum(id), g1 limit 1000;
QUERY PLAN
------------------------------------------------------------------------------
Limit
Output: (sum(id)), v1, v2, (generate_series(1::numeric, v1))
-> Sort
Output: (sum(id)), v1, v2, (generate_series(1::numeric, v1))
Sort Key: (sum(tbl_1k.id)), (generate_series(1::numeric, tbl_1k.v1))
-> ProjectSet
Output: (sum(id)), v1, v2, generate_series(1::numeric, v1)
-> GroupAggregate
Output: v1, sum(id), v2
Group By Key: tbl_1k.v1, tbl_1k.v2
-> Sort
Output: v1, v2, id
Sort Key: tbl_1k.v1, tbl_1k.v2
-> Seq Scan on srf_fusion.tbl_1k
Output: v1, v2, id
(15 rows)
create table agg_group as
select sum(id), v1,v2,generate_series(1,v1) as g1 from tbl_1k group by v1,v2 order by sum(id), g1 limit 1000;
set enable_hashagg=on;
explain (costs off, verbose)
select sum(id), v1,v2,generate_series(1,v1) as g1 from tbl_1k group by v1,v2 order by sum(id), g1 limit 1000;
QUERY PLAN
------------------------------------------------------------------------------
Limit
Output: (sum(id)), v1, v2, (generate_series(1::numeric, v1))
-> Sort
Output: (sum(id)), v1, v2, (generate_series(1::numeric, v1))
Sort Key: (sum(tbl_1k.id)), (generate_series(1::numeric, tbl_1k.v1))
-> ProjectSet
Output: (sum(id)), v1, v2, generate_series(1::numeric, v1)
-> HashAggregate
Output: v1, sum(id), v2
Group By Key: tbl_1k.v1, tbl_1k.v2
-> Seq Scan on srf_fusion.tbl_1k
Output: v1, v2, id
(12 rows)
create table agg_hash as
select sum(id), v1,v2,generate_series(1,v1) as g1 from tbl_1k group by v1,v2 order by sum(id), g1 limit 1000;
-- Compare results to hash aggregation results
(select * from agg_group except select * from agg_hash)
union all
(select * from agg_hash except select * from agg_group);
sum | v1 | v2 | g1
-----+----+----+----
(0 rows)
drop table tbl_1k,agg_group,agg_hash;
create table few(id int, dataa text, datab text);
insert into few values(1, 'a', 'foo'), (2, 'a', 'bar'), (3, 'b', 'bar');
explain (costs off)
select id, lag(id) over(order by id), count(*) over(), generate_series(1, 3) from few order by 1,2,3,4;
QUERY PLAN
--------------------------------------------------------------------------------------------------------------
Sort
Sort Key: id, (lag(id) OVER (ORDER BY id USING = NULLS LAST)), (count(*) OVER ()), (generate_series(1, 3))
-> ProjectSet
-> WindowAgg
-> WindowAgg
-> Sort
Sort Key: id
-> Seq Scan on few
(8 rows)
select id, lag(id) over(order by id), count(*) over(), generate_series(1, 3) from few order by 1,2,3,4;
id | lag | count | generate_series
----+-----+-------+-----------------
1 | | 3 | 1
1 | | 3 | 2
1 | | 3 | 3
2 | 1 | 3 | 1
2 | 1 | 3 | 2
2 | 1 | 3 | 3
3 | 2 | 3 | 1
3 | 2 | 3 | 2
3 | 2 | 3 | 3
(9 rows)
drop table few;
create table part_tsrf(a int,b int) partition by range(a) (partition p1 values less than (50), partition p2 values less than (MAXVALUE));
insert into part_tsrf(a,b) select (RANDOM() * 100)::int, generate_series(1, 100);
create table tsrf as select * from part_tsrf;
--scan/join contains srf
explain (costs off, verbose)
SELECT a,generate_series(1,a+b) FROM part_tsrf;
QUERY PLAN
----------------------------------------------------------
ProjectSet
Output: a, generate_series(1, (a + b))
-> Partition Iterator
Output: a, b
Iterations: 2
-> Partitioned Seq Scan on srf_fusion.part_tsrf
Output: a, b
Selected Partitions: 1..2
(8 rows)
create table t1 as SELECT a,generate_series(1,a+b) FROM part_tsrf;
create table t2 as SELECT a,generate_series(1,a+b) FROM tsrf;
(select * from t1 except select * from t2)
union all
(select * from t2 except select * from t1);
a | generate_series
---+-----------------
(0 rows)
drop table t1, t2;
--agg contsins srf
explain (costs off, verbose)
SELECT generate_series(1, max(a*b)), (a+b) % 1000 + 1 FROM part_tsrf group by (a+b) % 1000;
QUERY PLAN
--------------------------------------------------------------------------------------------
ProjectSet
Output: generate_series(1, (max((a * b)))), ((((a + b) % 1000)) + 1), (((a + b) % 1000))
-> HashAggregate
Output: max((a * b)), (((a + b) % 1000))
Group By Key: ((part_tsrf.a + part_tsrf.b) % 1000)
-> Partition Iterator
Output: ((a + b) % 1000), a, b
Iterations: 2
-> Partitioned Seq Scan on srf_fusion.part_tsrf
Output: ((a + b) % 1000), a, b
Selected Partitions: 1..2
(11 rows)
create table t1 as SELECT generate_series(1, max(a*b)), (a+b) % 1000 + 1 FROM part_tsrf group by (a+b) % 1000;
create table t2 as SELECT generate_series(1, max(a*b)), (a+b) % 1000 + 1 FROM tsrf group by (a+b) % 1000;
(select * from t1 except select * from t2)
union all
(select * from t2 except select * from t1);
generate_series | ?column?
-----------------+----------
(0 rows)
drop table t1, t2, part_tsrf, tsrf;
drop schema srf_fusion cascade;