There are two implementation for data paginate.
SELECT
(SELECT count(*) FROM (SELECT * FROM "items") m) :: INT AS total,
"t".*
FROM (SELECT *
FROM "items") AS "t"
LIMIT '10';
Select count("t".*) over () as total, "t".*
FROM (SELECT *
FROM "items") AS "t"
LIMIT '10';
the performance is huge different, and it seems the second one use lots of time to calculate count(*) over ().
I guess Postgres calculate total
for every row first, then limit on result, instead of in subquery(first one), it do limit first and then calculate the sub-query?
答案 0 :(得分:0)
我测试了1000000行,并且您的两个查询的执行计划确认了您的描述:
没有窗口功能:
QUERY PLAN
---------------------------------------------------------------------------------------------------------------------------------------
Limit (cost=17906.01..17906.19 rows=10 width=15) (actual time=348.125..348.132 rows=10 loops=1)
Buffers: shared hit=5407
InitPlan 1 (returns $0)
-> Aggregate (cost=17906.00..17906.01 rows=1 width=8) (actual time=348.081..348.081 rows=1 loops=1)
Buffers: shared hit=5406
-> Seq Scan on items items_1 (cost=0.00..15406.00 rows=1000000 width=0) (actual time=0.015..166.658 rows=1000000 loops=1)
Buffers: shared hit=5406
-> Seq Scan on items (cost=0.00..17906.00 rows=1000000 width=15) (actual time=348.122..348.127 rows=10 loops=1)
Buffers: shared hit=5407
Planning time: 0.386 ms
Execution time: 348.252 ms
(11 rows)
具有窗口功能:
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------
Limit (cost=0.00..0.28 rows=10 width=19) (actual time=980.923..980.941 rows=10 loops=1)
Buffers: shared hit=5406, temp read=2374 written=2564
-> WindowAgg (cost=0.00..27906.00 rows=1000000 width=19) (actual time=980.920..980.935 rows=10 loops=1)
Buffers: shared hit=5406, temp read=2374 written=2564
-> Seq Scan on items (cost=0.00..15406.00 rows=1000000 width=11) (actual time=0.041..169.046 rows=1000000 loops=1)
Buffers: shared hit=5406
Planning time: 0.228 ms
Execution time: 986.896 ms
(8 rows)
花费700毫秒来处理窗口函数,这是执行时间的主要部分。
窗口函数是在结果集生成之后计算出来的,因此这并不奇怪。