简体   繁体   中英

Postgres window function calculate order?

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?

I tested with 1000000 rows and the execution plans for your two queries confirm what you describe:

Without window function:

                                                              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)

With window function:

                                                          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 milliseconds are spent processing the window function, which is the lion's share of the execution time.

Window functions are calculated after the result set has been generated, so that is not really surprising.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM