uni*_*nop 6 sql postgresql pagination
假设我像这样做分页:
SELECT article_id,
article_content
FROM articles
ORDER BY article_rating
OFFSET (page - 1) * items_per_page
LIMIT items_per_page;
Run Code Online (Sandbox Code Playgroud)
我有一个索引(article_rating,article_id).
我的问题是:如果我找到一篇文章的最有效方法是什么
a)知道article_id
b)知道排序是ORDER BY article_rating?
它需要高效,因为我会经常进行这种类型的查询.
如果它不仅吐出页码,而且还吐出该页面上的所有文章,那就更好了.
因此,例如,如果所有文章按其评级排序,并且每十个文章都放在不同的页面上,我想弄清楚ID为839的文章在哪个页面上.
我正在使用PostgreSQL 8.4(如果需要,我愿意更新).
谢谢!
编辑:
正如下面的评论中指出的,我的查询可能看起来像这样:
SELECT article_id,
article_content
FROM articles
ORDER BY article_rating,
article_id
OFFSET (page - 1) * items_per_page
LIMIT items_per_page;
Run Code Online (Sandbox Code Playgroud)
编辑请参阅下面的第二个查询,它比第一个查询要好得多。
假设 Postgres 9.0 或更高版本,您必须使用窗口函数来获取每个项目的 row_number 。然后,将特定文章的 row_number 除以 items_per_page (和 round)以获得页码。唯一可用的效率改进是至少不查询相关文章之后的文章。所以你会得到这样的东西:
Select ceiling(rowNumber/items_per_page)
from (
SELECT article_id
, article_content
, row_number() over (order by article_rating, article_id)
as rowNumber
FROM articles
where article_rating <= (select article_rating
from articles
where article_id = 'xxxx' )
ORDER BY article_rating,
article_id
) x
where article_id = 'xxxx'
Run Code Online (Sandbox Code Playgroud)
编辑回答评论中的问题。是的,我刚刚意识到有一种更好的方法可以做到这一点。通过运行 count(*) 我们只遍历索引。
Select ceiling(count(*)/items_per_page)
FROM articles
where article_rating < (select article_rating
from articles
where article_id = 'xxxx' )
or ( article_rating = (select article_rating
from articles
where article_id = 'xxxx' )
and article_id <= 'xxxx')
Run Code Online (Sandbox Code Playgroud)
通常我们不喜欢 WHERE 子句中的 OR 子句,因为它们会降低性能,但是这个应该非常安全,因为如果对article_ rating 建立索引,每个子句都应该是可优化的。
| 归档时间: |
|
| 查看次数: |
1394 次 |
| 最近记录: |