Saltar al contenido

MySQL – ¿Paginación basada en cursor UUID/created_at?

Posterior a de una prolongada compilación de datos dimos con la respuesta esta duda que pueden tener ciertos los usuarios. Te dejamos la solución y esperamos serte de mucha apoyo.

Solución:

WHERE   created_at <= x
  AND ( created_at < x OR uuid < y )
ORDER BY created_at DESC,
         uuid       DESC

o este equivalente:

WHERE (     created_at < x
       OR ( created_at = x AND uuid < y )
      )
ORDER BY created_at DESC,
         uuid       DESC

Esta técnica funciona para cualquier par de columnas donde la primera (created_at) podría tener duplicados y el segundo es único (uuid o id).

Y esto es obligatorio:

INDEX(created_at, uuid)

Tenga en cuenta que ambas partes del WHERE son DESC. mezclando ASC y DESC anulará la usabilidad del INDEX. (MySQL 8.0 puede solucionar eso).

Tenga en cuenta también que esto supone que no le importa en qué orden están las filas cuando created_at está duplicado, pero usted quiere un coherente ordenando Tenga en cuenta que uuid será aparentemente aleatorio, pero aún consistente. Con eso dicho, id (con o sin Galera) y uuid funcionan igual de bien.

(Los UUID apestan, pero eso es un Discusión diferente.)

Más en paginación sin usar OFFSET .

Responderé lo que preguntaste, pero primero déjame decirte que no entiendo por qué quieres hacer eso. Una identificación autoincremental es muy buena para esta tarea. Pero también es correcto usar una columna de marca de tiempo, porque es una mala práctica confiar en una identificación para ordenar. ¿Por qué? Porque hay casos en los que su orden puede no ser cronológico, por ejemplo, si usa el clúster de Galera y tiene conmutación por error.

Para hacer lo que pediste, primero crea este índice:

ALTER TABLE users
    ADD INDEX idx_created_at_uuid (created_at, uuid);

El orden de las columnas es importante. Si lo invierte, el índice no será útil.

Ahora solo necesita ejecutar una consulta como esta:

SELECT some_columns
    FROM users
    WHERE created_at <= x AND uuid = y
    ORDER BY created_at DESC;

uuid solo es necesario porque created_at no es único. Si created_at no es la primera columna, MySQL tendrá que leer todas las filas y copiarlas en una tabla temporal (que podría estar en la memoria o en el disco) para ordenarlas.

Si decide usar la identificación, solo conserve los fragmentos anteriores, pero reemplácelos uuid con id.

Reseñas y valoraciones

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *