2011-06-06 26 views
6

哪个页面比方说,我不分页这样的:分页:找出一个项目是(给定的主键和排序顺序)

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的)

我的问题是:什么是要找出哪个网页上的文章是最有效的方式,如果我

一)知道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

如果有多个项目具有相同的'article_rating',那么这可能会特别棘手 - 它可能出现在多个不同的页面上。 – 2011-06-06 14:43:05

+0

@Damien_The_Unbeliever:你说得对,如果两篇或多篇文章具有相同的评分,我应该可能已经完成ORDER BY article_rating,article_id以获得确定性顺序。 – unicornop 2011-06-06 14:47:27

回答

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子句,因为它们可能会降低性能的条款,但是这一次应该是相当安全的,因为每一个条款应该如果article_rating被索引是优化的。

+0

非常感谢您的快速回复。我担心它会降低到这样的程度。查询可能会减慢页码越高,不是吗?有什么我可以做的,不要让执行时间取决于文章所在的页面? – unicornop 2011-06-06 15:45:11

+0

感谢您的编辑。我不幸的是在接下来的几天里将无法访问我的PostgreSQL机器,所以我无法测试它现在的实际表现。但我猜如果它只需要遍历索引,即使页码很高,它也应该非常快;我对这个假设是否正确? – unicornop 2011-06-06 23:06:04