"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Liberando o MongoDB: Por que a paginação baseada em cursor sempre supera a paginação baseada em deslocamento!

Liberando o MongoDB: Por que a paginação baseada em cursor sempre supera a paginação baseada em deslocamento!

Publicado em 2024-11-07
Navegar:714

Paginação é uma parte crítica de qualquer operação de banco de dados ao lidar com grandes conjuntos de dados. Ele permite dividir os dados em partes gerenciáveis, facilitando a navegação, o processamento e a exibição. O MongoDB fornece dois métodos de paginação comuns: baseado em deslocamento e baseado em cursor. Embora ambos os métodos tenham o mesmo propósito, eles diferem significativamente em desempenho e usabilidade, especialmente à medida que o conjunto de dados cresce.

Vamos mergulhar nas duas abordagens e ver por que a paginação baseada em cursor geralmente supera a paginação baseada em deslocamento.

1. Paginação baseada em deslocamento

A paginação baseada em deslocamento é simples. Ele recupera um número específico de registros a partir de um determinado deslocamento. Por exemplo, a primeira página pode recuperar os registros de 0 a 9, a segunda página recupera os registros de 10 a 19 e assim por diante.

No entanto, esse método tem uma desvantagem significativa: conforme você passa para páginas superiores, a consulta se torna mais lenta. Isso ocorre porque o banco de dados precisa pular os registros das páginas anteriores, o que envolve examiná-los.

Aqui está o código para paginação baseada em deslocamento:

async function offset_based_pagination(params) {
  const { page = 5, limit = 100 } = params;
  const skip = (page - 1) * limit;
  const results = await collection.find({}).skip(skip).limit(limit).toArray();
  console.log(`Offset-based pagination (Page ${page}):`, results.length, "page", page, "skip", skip, "limit", limit);
}

2. Paginação baseada em cursor

A paginação baseada em cursor, também conhecida como paginação de conjunto de chaves, depende de um identificador exclusivo (por exemplo, um ID ou carimbo de data/hora) para paginar os registros. Em vez de pular um certo número de registros, ele usa o último registro recuperado como ponto de referência para buscar o próximo conjunto.

Essa abordagem é mais eficiente porque evita a necessidade de digitalizar os registros antes da página atual. Como resultado, o tempo de consulta permanece consistente, independentemente da profundidade do conjunto de dados.

Aqui está o código para paginação baseada em cursor:

async function cursor_based_pagination(params) {
  const { lastDocumentId, limit = 100 } = params;
  const query = lastDocumentId ? { documentId: { $gt: lastDocumentId } } : {};
  const results = await collection
    .find(query)
    .sort({ documentId: 1 })
    .limit(limit)
    .toArray();
  console.log("Cursor-based pagination:", results.length);
}

Neste exemplo, lastDocumentId é o ID do último documento da página anterior. Ao consultar a próxima página, o banco de dados busca documentos com um ID maior que esse valor, garantindo uma transição perfeita para o próximo conjunto de registros.

3. Comparação de desempenho

Vamos ver o desempenho desses dois métodos com um grande conjunto de dados.

async function testMongoDB() {
    console.time("MongoDB Insert Time:");
    await insertMongoDBRecords();
    console.timeEnd("MongoDB Insert Time:");

  // Create an index on the documentId field
  await collection.createIndex({ documentId: 1 });
  console.log("Index created on documentId field");

  console.time("Offset-based pagination Time:");
  await offset_based_pagination({ page: 2, limit: 250000 });
  console.timeEnd("Offset-based pagination Time:");

  console.time("Cursor-based pagination Time:");
  await cursor_based_pagination({ lastDocumentId: 170000, limit: 250000 });
  console.timeEnd("Cursor-based pagination Time:");

  await client.close();
}

Image description

No teste de desempenho, você notará que a paginação baseada em deslocamento demora mais à medida que o número da página aumenta, enquanto o cursor A paginação baseada em permanece consistente, tornando-a a melhor escolha para conjuntos de dados grandes. Este exemplo também demonstra o poder da indexação. Tente remover o índice e veja o resultado também!

Por que a indexação é importante

Sem um índice, o MongoDB precisaria realizar uma varredura de coleção, o que significa que ele teria que examinar cada documento da coleção para encontrar os dados relevantes. Isto é ineficiente, especialmente quando o seu conjunto de dados cresce. Os índices permitem que o MongoDB encontre com eficiência os documentos que correspondem às condições da sua consulta, acelerando significativamente o desempenho da consulta.

No contexto da paginação baseada em cursor, o índice garante que a busca do próximo conjunto de documentos (com base em documentId) seja rápida e não prejudique o desempenho à medida que mais documentos são adicionados à coleção.

Conclusão

Embora a paginação baseada em deslocamento seja fácil de implementar, ela pode se tornar ineficiente com grandes conjuntos de dados devido à necessidade de digitalizar registros. A paginação baseada em cursor, por outro lado, fornece uma solução mais escalonável, mantendo o desempenho consistente independentemente do tamanho do conjunto de dados. Se você estiver trabalhando com grandes coleções no MongoDB, vale a pena considerar a paginação baseada em cursor para uma experiência mais suave e rápida.

Aqui está index.js completo para você executar localmente:

const { MongoClient } = require("mongodb");
const uri = "mongodb://localhost:27017";
const client = new MongoClient(uri);
client.connect();
const db = client.db("testdb");
const collection = db.collection("testCollection");

async function insertMongoDBRecords() {
  try {
    let bulkOps = [];

    for (let i = 0; i  0) {
      await collection.bulkWrite(bulkOps);
      console.log("? Inserted records till now -> ", bulkOps.length);
    }

    console.log("MongoDB Insertion Completed");
  } catch (err) {
    console.error("Error in inserting records", err);
  }
}

async function offset_based_pagination(params) {
  const { page = 5, limit = 100 } = params;
  const skip = (page - 1) * limit;
  const results = await collection.find({}).skip(skip).limit(limit).toArray();
  console.log(`Offset-based pagination (Page ${page}):`, results.length, "page", page, "skip", skip, "limit", limit);
}

async function cursor_based_pagination(params) {
  const { lastDocumentId, limit = 100 } = params;
  const query = lastDocumentId ? { documentId: { $gt: lastDocumentId } } : {};
  const results = await collection
    .find(query)
    .sort({ documentId: 1 })
    .limit(limit)
    .toArray();
  console.log("Cursor-based pagination:", results.length);
}

async function testMongoDB() {
  console.time("MongoDB Insert Time:");
  await insertMongoDBRecords();
  console.timeEnd("MongoDB Insert Time:");

  // Create an index on the documentId field
  await collection.createIndex({ documentId: 1 });
  console.log("Index created on documentId field");

  console.time("Offset-based pagination Time:");
  await offset_based_pagination({ page: 2, limit: 250000 });
  console.timeEnd("Offset-based pagination Time:");

  console.time("Cursor-based pagination Time:");
  await cursor_based_pagination({ lastDocumentId: 170000, limit: 250000 });
  console.timeEnd("Cursor-based pagination Time:");

  await client.close();
}

testMongoDB();

Declaração de lançamento Este artigo foi reproduzido em: https://dev.to/franklinthaker/unleashing-mongodb-why-cursor-based-pagination-outperforms-offset-based-pagination-every-time-4o30?1 Se houver alguma violação, por favor entre em contato com study_golang@163 .comdelete
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3