2016-07-26 49 views
0

我已经使用分页构建了一个基于PHP的web应用程序。我做了一个Couchbase和Postgres版本。我不得不放弃N1QL,因为它表现糟糕(也许我会提出另一个问题)。所以我将项目从N1QL迁移到了视图。我注意到,在低页码(例如1,10,50每页48条记录)时,性能要优于postgres(0.07s vs 0.11s),但是在高页数时(例如4000 - > 1.5秒和16000 - > 5秒)表现非常糟糕。我使用跳过+限制与本地CB库分页。Couchbase的PHP分页在页码很高时变得非常缓慢

任何想法?

PHP:

public static function findByPage($recordsPerPage, $page) { 
     $query = CouchbaseViewQuery::from("dev_".static::COLLECTION_NAME, "get_".static::COLLECTION_NAME."")->reduce(false)->skip($recordsPerPage*($page-1))->limit($recordsPerPage)->custom(array("full_set"=> "true")); 
     $data = DB::getDB()->query($query, null, true); 
     // var_dump($data); 
     $objects = array(); 
     foreach($data["rows"] as $row) { 
      $objects[] = static::find($row["key"]); 
     } 
     return $objects; 
    } 

一的观点(他们几乎都是一样的):

function (doc, meta) { 
    if(doc.collection == "green_area") { 
    emit(doc._id, null); 
    } 
} 
+1

如果您在查询和索引以及EXPLAIN和Couchbase版本中发布单独的问题,我们很乐意查看您的N1QL分页。 – geraldss

+1

谢谢你,如果你想看看,我已经提出了一个单独的问题。如果它工作,我会再次执行N1QL,等待Couchbase CE 4.5.0并使用视图+全文搜索或使用PostgreSQL。 –

回答

0

这是一个享有一个已知的限制。问题是,没有办法知道视图索引记录4000有多远。当您请求记录4000-4004时,视图引擎不需要生成5条记录,它必须生成4000个记录,它立即丢弃,然后将下一个5记录下来。由于视图的性质并且必须分散 - 从多个节点收集产生一个单一的结果,这可能是非常昂贵的,因为你已经观察到了。出于这个原因,不鼓励使用“跳过”选项

相反,建议您使用“范围”选项。这种方式的工作原理是最初将范围指定为开放(即,使得它将包括所有记录),这样的示例将从\ u00到\ u0fff(全范围的unicode字符)并返回例如10条记录。然后,您会记住第10条记录的内容,并将其指定为下一页的范围的开始)。例如,如果您的第10条记录是“啤酒”,那么您将指定从“啤酒”到\ u0fff的范围。现在这将包括啤酒作为第一个结果,有两种方法可以解决这个问题。首先是要求11个结果并忽略第一个结果。解决这个问题的第二种方法是将范围指定为'啤酒\ u00'到\ u0fff,该范围从'beer'之后的第一个可能的记录开始。

这Couchbase的博客文章进入更多的细节:http://blog.couchbase.com/pagination-couchbase

值得一提的是,N1QL一般会产生不能够猜出第n个记录将在指数的同样的问题,不一定是回答你的问题。