2016-07-26 66 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個記錄將在指數的同樣的問題,不一定是回答你的問題。