as
select generate_series(1, 2000000000)::int i;
set max_parallel_workers_per_gather = 0;
select count(*) from t;
-> 14.5s, ~4000 IOPS, ~128kB/t = ~500MB/s
23080: pread(6,<data>,8192,0x10160000)
23080: pread(6,<data>,8192,0x10162000)
23080: pread(6,<data>,8192,0x10164000)
23080: pread(6,<data>,8192,0x10166000)
set max_parallel_workers_per_gather = 1;
select count(*) from t;
-> 35.6s, ~6000 IOPS, ~33kB/t = ~180MB/s 23080: pread(6,<data>,8192,0x10160000)
23081: pread(9,<data>,8192,0x10162000)
23080: pread(6,<data>,8192,0x10164000)
23081: pread(9,<data>,8192,0x10166000) • Parallel Sequential Scan’s goal is to divide tuple processing work up by handing out sequential blocks to parallel worker processes. • UFS doesn’t recognise this access pattern as sequential. Linux does, due to read-ahead “window”. ZFS apparently does too. • Maybe PostgreSQL is the only software to have come up with this diabolical access pattern, due to its process model and lack of AIO and direct I/O (for now). • Related: mixing two streams, read and write, in the same file. D25024 to fix that.