Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
SELECT * FROM test_table ORDER BY id LIMIT 100000, 30
SELECT * FROM test_table JOIN (SELECT id FROM test_table ORDER BY id LIMIT 100000, 30) as b ON b.id = test_table.id

postgres=# EXPLAIN ANALYZE SELECT * FROM medley ORDER BY n OFFSET 500000 LIMIT 30;
QUERY PLAN
-------------------------------------
Limit (cost=17258.34..17259.37 rows=30 width=37) (actual time=202.280..202.292 rows=30 loops=1)
-> Index Scan using n_idx on medley (cost=0.43..345158.43 rows=10000000 width=37)
(actual time=0.034..176.281 rows=500030 loops=1)
Planning time: 0.123 ms
Execution time: 202.323 ms
(4 rows)
postgres=# EXPLAIN ANALYZE SELECT * FROM medley JOIN
(SELECT n FROM medley ORDER BY n OFFSET 500000 LIMIT 30)
as b ON b.n = medley.n;
QUERY PLAN
------------------------------------------
Nested Loop (cost=12985.27..13239.79 rows=30 width=41) (actual time=132.953..133.150 rows=30 loops=1)
-> Limit (cost=12984.83..12985.61 rows=30 width=4)
(actual time=132.897..132.912 rows=30 loops=1)
-> Index Only Scan using n_idx on medley medley_1 (cost=0.43..259688.43 rows=10000000 width=4)
(actual time=0.032..107.005 rows=500030 loops=1)
Heap Fetches: 0
-> Index Scan using n_idx on medley (cost=0.43..8.45 rows=1 width=37)
(actual time=0.007..0.007 rows=1 loops=30)
Index Cond: (n = medley_1.n)
Planning time: 0.426 ms
Execution time: 133.200 ms
(8 rows)
WITH temp_rows AS (
SELECT n
FROM medley
ORDER BY n OFFSET 500000
LIMIT 30
)
SELECT * FROM medley WHERE medley.n = ANY(ARRAY(SELECT n FROM temp_rows)::uuid[])
EXPLAIN ANALYZE
SELECT *
FROM product
ORDER BY guid
OFFSET 200000
LIMIT 10
"Limit (cost=53081.04..53083.70 rows=10 width=427) (actual time=5338.193..5338.218 rows=10 loops=1)"
" -> Index Scan using "pk-product" on product (cost=0.42..107495.58 rows=405026 width=427) (actual time=0.026..5201.130 rows=200010 loops=1)"
"Planning time: 0.679 ms"
"Execution time: 5338.266 ms"
EXPLAIN ANALYZE
SELECT *
FROM product as a
JOIN (SELECT guid FROM product ORDER BY guid OFFSET 200000 LIMIT 30) as b ON b.guid = a.guid;
"Hash Join (cost=6114.90..35463.31 rows=30 width=443) (actual time=246.895..6361.194 rows=30 loops=1)"
" Hash Cond: (a.guid = product.guid)"
" -> Seq Scan on product a (cost=0.00..27829.26 rows=405026 width=427) (actual time=0.004..5820.195 rows=405026 loops=1)"
" -> Hash (cost=6114.53..6114.53 rows=30 width=16) (actual time=243.653..243.653 rows=30 loops=1)"
" Buckets: 1024 Batches: 1 Memory Usage: 2kB"
" -> Limit (cost=6113.31..6114.23 rows=30 width=16) (actual time=243.567..243.618 rows=30 loops=1)"
" -> Index Only Scan using "pk-product" on product (cost=0.42..12379.81 rows=405026 width=16) (actual time=0.011..129.707 rows=200030 loops=1)"
" Heap Fetches: 0"
"Planning time: 0.181 ms"
"Execution time: 6361.272 ms"
EXPLAIN ANALYZE
WITH temp_rows AS (
SELECT guid
FROM product
ORDER BY guid OFFSET 200000
LIMIT 30
)
SELECT * FROM product WHERE guid = ANY(ARRAY(SELECT guid FROM temp_rows)::uuid[])
"Index Scan using "pk-product" on product (cost=6115.26..6199.24 rows=10 width=427) (actual time=243.227..243.329 rows=30 loops=1)"
" Index Cond: (guid = ANY ($1))"
" CTE temp_rows"
" -> Limit (cost=6113.31..6114.23 rows=30 width=16) (actual time=243.037..243.089 rows=30 loops=1)"
" -> Index Only Scan using "pk-product" on product product_1 (cost=0.42..12379.81 rows=405026 width=16) (actual time=0.015..130.086 rows=200030 loops=1)"
" Heap Fetches: 0"
" InitPlan 2 (returns $1)"
" -> CTE Scan on temp_rows (cost=0.00..0.60 rows=30 width=16) (actual time=243.041..243.133 rows=30 loops=1)"
"Planning time: 0.154 ms"
"Execution time: 243.386 ms"
postgres=# EXPLAIN ANALYZE WITH temp_rows AS (
SELECT n
FROM medley
ORDER BY n OFFSET 500000
LIMIT 30
)
SELECT * FROM medley WHERE medley.n = ANY(ARRAY(SELECT n FROM temp_rows)::Int[]);
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------------------------------------
Index Scan using n_idx on medley (cost=12986.44..13034.53 rows=10 width=38) (actual time=138.009..138.107 rows=30 loops=1)
Index Cond: (n = ANY ($1))
CTE temp_rows
-> Limit (cost=12984.63..12985.41 rows=30 width=4) (actual time=137.945..137.953 rows=30 loops=1)
-> Index Only Scan using n_idx on medley medley_1 (cost=0.43..259694.04 rows=10000374 width=4) (actual time=0.038..110.982 rows=500030 loops=1)
Heap Fetches: 0
InitPlan 2 (returns $1)
-> CTE Scan on temp_rows (cost=0.00..0.60 rows=30 width=4) (actual time=137.950..137.968 rows=30 loops=1)
Planning time: 0.219 ms
Execution time: 138.158 ms
(10 rows)
cost=725946.11..725946.11 rows=1 width=1147) (actual time=1554.900..1554.915 rows=50 loops=1cost=725954.67..725962.71 rows=1 width=2041) (actual time=1200.102..1201.138 rows=50 loops=1cost=1654277.66..1654362.74 rows=10 width=2041) (actual time=2729.149..2729.608 rows=50 loops=1Index Scan (cost=1310619.54..1310704.63 rows=10 width=2041) (actual time=1906.651..1907.164 rows=50 loops=1)
CTE temp_rows
-> Limit (cost=1310617.85..1310617.97 rows=50 width=32) (actual time=1906.502..1906.517 rows=50 loops=1)
-> Sort (cost=1310542.85..1311220.85 rows=271201 width=32) (actual time=1899.475..1904.427 rows=30050 loops=1)
-> Bitmap Heap Scan (cost=399032.63..1289016.16 rows=271201 width=32) (actual time=821.209..1723.774 rows=218436 loops=1)
-> Bitmap Index Scan (cost=0.00..398964.83 rows=305711 width=0) (actual time=705.200..705.200 rows=320530 loops=1)
InitPlan 2 (returns $1)
-> CTE Scan on temp_rows (cost=0.00..1.00 rows=50 width=16) (actual time=1906.506..1906.544 rows=50 loops=1)
Planning time: 0.966 ms
Execution time: 1911.184 ms
(cost=1365076.05..1365161.13 rows=10 width=2501) (actual time=2078.275..2078.763 rows=50 loops=1)
(cost=2589.09..2674.17 rows=10 width=2501) (actual time=59.720..60.222 rows=50 loops=1)
Index Scan (cost=2589.09..2674.17 rows=10 width=2501) (actual time=59.720..60.222 rows=50 loops=1)
-> Limit (cost=1294.04..2587.51 rows=50 width=32) (actual time=23.419..59.575 rows=50 loops=1)
-> Index Scan (cost=0.56..11409104.75 rows=441025 width=32) (actual time=0.579..59.549 rows=100 loops=1)
-> CTE Scan on temp_rows (cost=0.00..1.00 rows=50 width=16) (actual time=23.423..59.661 rows=50 loops=1)
Planning time: 0.647 ms
Execution time: 60.287 ms
Ну, учитывая что в БД хранятся не массивы, а гомогенные мультимножества — это логично для любой БД, как мне кажется.
Пять способов пагинации в Postgres, от базовых до диковинных