Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
Как видите, Sort функционирует совсем не так, как Limit. Он сразу загружает все доступные данные из субплана в буфер прежде, чем что-либо возвращать. Затем он сортирует буфер с помощью алгоритма Quicksort и, наконец, возвращает первое отсортированное значение.
select * from table where id = (select max(id) from table)
илиselect * from table order by id limit 1
select * from t1 where id = (select max(id) from t1) -- 12ms
select * from t1 order by id desc limit 1 -- 12ms
select * from t2 where id = (select max(id) from t2) -- 12ms
select * from t2 order by id desc limit 1 -- 12ms
select * from t1 where summa = (select max(summa) from t1) -- 5206ms
select * from t1 order by summa desc limit 1 -- 2159ms
select * from t2 where summa = (select max(summa) from t2) -- 4990ms
select * from t2 order by summa desc limit 1 -- 2240ms
EXPLAIN ANALYZE
select * from t1 where id = (select max(id) from t1)
------------------
Index Scan using t1_pkey on t1 (cost=0.09..9.52 rows=1 width=136) (actual time=0.100..0.102 rows=1 loops=1)
Index Cond: ((id)::bigint = $1)
InitPlan 2 (returns $1)
-> Result (cost=0.08..0.09 rows=1 width=0) (actual time=0.084..0.085 rows=1 loops=1)
InitPlan 1 (returns $0)
-> Limit (cost=0.00..0.08 rows=1 width=8) (actual time=0.078..0.080 rows=1 loops=1)
-> Index Scan Backward using t1_pkey on t1 (cost=0.00..885209.13 rows=10556080 width=8) (actual time=0.075..0.075 rows=1 loops=1)
Index Cond: ((id)::bigint IS NOT NULL)
Total runtime: 0.179 ms
EXPLAIN ANALYZE
select * from t1 order by id desc limit 1
------------------
Limit (cost=0.00..0.08 rows=1 width=136) (actual time=0.028..0.029 rows=1 loops=1)
-> Index Scan Backward using t1_pkey on t1 (cost=0.00..858818.93 rows=10556080 width=136) (actual time=0.024..0.024 rows=1 loops=1)
Total runtime: 0.120 ms
EXPLAIN ANALYZE
select * from t1 where summa = (select max(summa) from t1)
------------------
Seq Scan on t1 (cost=279653.01..559306.01 rows=948 width=136) (actual time=14349.590..14431.243 rows=1 loops=1)
Filter: (summa = $0)
InitPlan 1 (returns $0)
-> Aggregate (cost=279653.00..279653.01 rows=1 width=6) (actual time=12237.067..12237.068 rows=1 loops=1)
-> Seq Scan on t1 (cost=0.00..253262.80 rows=10556080 width=6) (actual time=0.003..5837.878 rows=10556080 loops=1)
Total runtime: 14431.325 ms
EXPLAIN ANALYZE
select * from t1 order by summa desc limit 1
------------------
Limit (cost=306043.20..306043.20 rows=1 width=136) (actual time=11477.247..11477.248 rows=1 loops=1)
-> Sort (cost=306043.20..332433.40 rows=10556080 width=136) (actual time=11477.245..11477.245 rows=1 loops=1)
Sort Key: summa
Sort Method: top-N heapsort Memory: 25kB
-> Seq Scan on t1 (cost=0.00..253262.80 rows=10556080 width=136) (actual time=0.008..5866.153 rows=10556080 loops=1)
Total runtime: 11477.302 ms
Путешествие запроса Select через внутренности Постгреса