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
.