【问题标题】:Can this postgres paging sql's performance be improved?这个postgres分页sql的性能可以提高吗?
【发布时间】:2019-10-19 10:13:51
【问题描述】:

我有一个 HTTP 客户端,它希望简单地发送查询字符串中的偏移量来处理分页,例如 http://foo.com/cars?offset=50

作为响应,他们得到一个模型,其中包含项目总数和数据数组。 {"totalitemcount":100, "data":[{"id":1,"name":"Porsche"},{"id":2, "name":"Ferrari"}]}

我用来执行此操作的 SQL 如下:

select count(items.id) over() as totalitemcount, items.* from ( 
      select * from cars 
      order by id
      ) as items 
limit 20 
offset 50

我不确定这种方法的性能如何,并且想知道上述限制是否可以进行更改以改进它?

【问题讨论】:

  • 我不确定内部ORDER BY 是否会被外部SELECT 考虑在内。
  • 强烈建议避免使用OFFSET 进行分页,因为它需要扫描所有前面的记录并且根本没有性能。您应该改用 id 字段进行过滤/分页。看到这篇很棒的帖子:use-the-index-luke.com/sql/partial-results/fetch-next-page

标签: sql postgresql pagination paging


【解决方案1】:

最好的方法是先这样查询:

SELECT * FROM cars 
ORDER BY id
LIMIT 20;

然后记住最后一个id

下一页是用

检索的
SELECT * FROM cars 
WHERE id > [the id you remembered]
ORDER BY id
LIMIT 20;

等等。

这样您不会得到结果的总数,但会提高效率。

真的需要确切的总数吗?如果一个近似值就足够了,试试this blog post末尾的想法。

【讨论】:

  • 你怎么知道在客户端有多少页面要链接到例如1,2,3,下一个,最后一个,如果没有总计数。如果 id 3, 6,8 被删除怎么办?下一页的id是怎么计算的?
  • 因为你不知道这个方法的总页数,所以你不能马上知道会有多少页。但是,您不需要知道下一个id:条件id > [last id] 会自动找到下一个id,它可以使用列上的索引来有效地做到这一点。
猜你喜欢
  • 2012-02-11
  • 1970-01-01
  • 1970-01-01
  • 2014-10-27
  • 2012-11-23
  • 2020-07-11
  • 1970-01-01
  • 2021-12-18
  • 1970-01-01
相关资源
最近更新 更多