让我说我像这样做分页:
SELECT article_id,
article_content
FROM articles
ORDER BY article_rating
OFFSET (page - 1) * items_per_page
LIMIT items_per_page;
我的索引超过(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;
答案 0 :(得分:2)
编辑请参阅下面的第二个查询,它比第一个查询要好得多。
假设Postgres 9.0或更高版本,您必须使用窗口函数来获取每个项目的row_number。然后用items_per_page(和round)划分特定文章的row_number以获取页码。唯一可用的效率改进是至少不查询之后的文章。所以你得到这样的东西:
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'
编辑回复评论中的问题。是的,我刚刚意识到有一个更好的方法来做到这一点。通过运行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')
通常我们不喜欢WHERE子句中的OR子句,因为它们会降低性能,但是这个应该非常安全,因为如果article_rating被索引,每个子句都应该是可优化的。