2016-07-26 19 views
0

Я создал веб-приложение на основе PHP с разбивкой на страницы. Я сделал как Couchbase, так и версию Postgres. Мне пришлось отказаться от N1QL, потому что у него была ужасная производительность (возможно, я сделаю еще один вопрос для этого). Поэтому я перенес проект из N1QL в представления. Я заметил, что, хотя на низком номере страницы (например, 1, 10, 50 с 48 записями на странице) производительность была лучше, чем postgres (0,07 с против 0,11), но при высоком номере страницы (например, 4000 -> 1,5 секунды и 16000 -> 5 секунд) производительность очень плохая. Я использую skip + limit для разбивки на страницы с помощью собственной библиотеки CB.PHP разбиение на страницы с Couchbase очень медленно на высоких страницах страницы

Любые идеи?

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, который начинается с первой возможной записи после «пива».

блог

Это Couchbase пост переходит в подробности: http://blog.couchbase.com/pagination-couchbase

Стоит отметить, что N1QL в целом будет иметь ту же проблему не в состоянии угадать, где энный запись будет в индексе и не обязательно будет ответьте на свою проблему.