【发布时间】:2015-11-26 10:39:47
【问题描述】:
在没有索引的理论场景中,带限制的 order by 必须扫描所有数据,然后应用 order by 然后只应用限制,因为我们只能在之后获得前 10 行(例如)排序。
但 postgres 在这里稍微聪明一点,下面的计划给出了故事。
按限制排序
learning=# explain (analyze,buffers) select * from temp order by userid limit 10;
QUERY PLAN
-------------------------------------------------------------------------------------------------------------------------------
Limit (cost=81745.51..81745.54 rows=10 width=41) (actual time=2064.275..2064.278 rows=10 loops=1)
Buffers: shared hit=13 read=18644
-> Sort (cost=81745.51..86735.41 rows=1995958 width=41) (actual time=2064.273..2064.274 rows=10 loops=1)
Sort Key: userid
Sort Method: top-N heapsort Memory: 25kB
Buffers: shared hit=13 read=18644
-> Seq Scan on temp (cost=0.00..38613.58 rows=1995958 width=41) (actual time=35.053..1652.660 rows=1995958 loops=1)
Buffers: shared hit=10 read=18644
Planning time: 0.167 ms
Execution time: 2064.335 ms
(10 rows)
无限制下单
learning=# explain (analyze,buffers) select * from temp order by userid;
QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------
Sort (cost=308877.61..313867.51 rows=1995958 width=41) (actual time=2685.680..3293.698 rows=1995958 loops=1)
Sort Key: userid
Sort Method: external merge Disk: 99504kB
Buffers: shared hit=42 read=18612, temp read=12440 written=12440
-> Seq Scan on temp (cost=0.00..38613.58 rows=1995958 width=41) (actual time=0.069..286.556 rows=1995958 loops=1)
Buffers: shared hit=42 read=18612
Planning time: 0.066 ms
Execution time: 3540.545 ms
(8 rows)
我对此的假设是 postgres 使用一种称为堆排序(众所周知)的算法,并在获得前 N(限制)行时停止。
从this 可视化,我无法理解这是如何工作的?任何人都可以理解这一点。我的假设是否正确?
【问题讨论】:
标签: database performance postgresql