2016-07-26 4 views
0

J'ai construit une application web basée sur PHP avec pagination. J'ai fait à la fois une version Couchbase et une version Postgres. J'ai dû abandonner N1QL parce qu'il avait des performances terribles (peut-être que je ferai une autre question pour ça). J'ai donc migré le projet de N1QL vers les vues. J'ai remarqué que, à faible nombre de pages (par exemple 1, 10, 50 avec 48 enregistrements par page), les performances étaient meilleures que les postgres (0.07s vs 0.11s), mais avec un nombre de pages élevé (par exemple 4000 -> 1.5 secondes et 16000 -> 5 secondes) la performance est très mauvaise. J'utilise skip + limite pour la pagination avec la librairie CB native.pagination PHP avec Couchbase devient très lent à des numéros de page élevés

Des idées?

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; 
    } 

L'un des points de vue (ils sont à peu près tous les mêmes):

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

Serait heureux de regarder dans votre pagination N1QL si vous postez une question distincte avec vos requêtes et vos index et la version EXPLAIN et Couchbase. – geraldss

+1

Merci, j'ai fait une question distincte pour cela si vous voulez jeter un coup d'oeil. Je ferai à nouveau N1QL si cela fonctionne, attendez Couchbase CE 4.5.0 et utilisez les vues + recherche plein texte ou utilisez PostgreSQL. –

Répondre

0

Ceci est une limitation connue avec vue. Le problème est qu'il n'y a aucun moyen de savoir à quelle distance de l'enregistrement de l'index de vue 4000 est. Lorsque vous demandez des enregistrements 4000-4004, le moteur de vue ne doit pas générer seulement 5 enregistrements, il doit générer 4000 qu'il supprime immédiatement et vous donne ensuite le 5 suivant. En raison de la nature des vues et de la dispersion rassembler à partir de plusieurs nœuds pour produire un résultat unique cela peut être extrêmement coûteux comme vous l'avez observé. Pour cette raison, il est déconseillé d'utiliser l'option 'skip'

A la place, il est recommandé d'utiliser l'option 'range'. La façon dont cela fonctionne est de spécifier initialement la plage comme ouverte (c'est-à-dire de telle sorte qu'elle inclurait tous les enregistrements), un exemple de ceci serait de \ u00 à \ u0fff (La gamme complète des caractères Unicode) et de retourner par exemple. 10 enregistrements. Vous vous rappellerez alors quel était le 10ème enregistrement et spécifiez cela comme le début de votre gamme pour la page suivante). Par exemple, si votre dixième disque était «bière», alors vous spécifieriez la plage allant de «bière» à \ u0fff. Maintenant, cela inclurait la bière comme premier résultat, il y a deux façons de résoudre cela. Le premier est de demander 11 résultats et d'ignorer le premier. La deuxième façon de résoudre ce problème serait de spécifier la plage «bière \ u00» à \ u0fff qui commence au premier enregistrement possible après «bière».

Ce billet de blog Couchbase va dans plus de détails: http://blog.couchbase.com/pagination-couchbase

Il convient de noter que N1QL aura généralement le même problème de ne pas être en mesure de deviner où le nième enregistrement sera dans l'index et ne sera pas nécessairement la répondre à votre problème.