【发布时间】:2014-06-16 19:36:44
【问题描述】:
在 PostgreSQL 9.3 中尝试使用窗口函数时,我遇到了一个相当有趣的案例。与OFFSET vs. ROW_NUMBER() 上的答案直接矛盾的是,我发现窗口函数实际上快 比OFFSET。
使用偏移量,大约需要 2500 毫秒:
select part_no, description
from inventory
order by part_no
limit 1000 offset 400000
使用 row_number(),大约需要 450 毫秒:
select *
from (select part_no, description, row_number() OVER ()
from inventory
order by part_no) AS ss
where row_number >= 400001
limit 1000
这个(新分析的)表有大约 450,000 行,part_no 被索引。 EXPLAIN 表示在 row_number() 情况下正在执行索引扫描,在 OFFSET 情况下正在执行顺序扫描。
我尝试了不同偏移量大小的 OFFSET、row_number() 组合以及索引和未索引排序顺序。所有时间都是几次运行的近似平均值(查询时间通常非常一致。)
-------indexed------- ------unindexed------
offset by OFFSET row_number() OFFSET row_number()
==========================================================
400000 2500ms 450ms 500ms 650ms
40000 80ms 60ms 850ms 650ms
4000 30ms 30ms 390ms 650ms
我想这里真正的问题是;在这两种情况下,查询规划器有什么不同,我怎样才能让它做出更好的选择(特别是在大偏移量+索引列的情况下)?
【问题讨论】:
标签: sql postgresql query-optimization