sql >> Base de Datos >  >> RDS >> Mysql

mySQL - Paginación de filas filtradas

No puede saber cuál es la primera identificación en una página dada, porque los números de identificación no son necesariamente secuenciales. En otras palabras, podría haber espacios en la secuencia, por lo que las filas en la quinta página de 100 filas no necesariamente comienzan en id 500. Podría comenzar en id 527, por ejemplo, es imposible saberlo.

Dicho de otra manera:id es un valor, no un número de fila.

Una posible solución si su cliente avanza a través de las páginas en orden ascendente es que cada solicitud REST obtenga datos, anote los más grandes valor de id en esa página, luego lo usa en la siguiente Solicitud REST para que consulte los valores de identificación que son más grandes.

SELECT ... FROM ... WHERE filterKey = filterValue 
AND id > id_of_last_match_of_previous_page

Pero si su solicitud REST puede obtener cualquier página aleatoria, esta solución no funciona. Depende de haber obtenido ya la página anterior.

Otra solución es usar el LIMIT <x> OFFSET <y> sintaxis. Esto le permite solicitar cualquier página arbitraria. LIMIT <y>, <x> funciona igual, pero por alguna razón, x e y se invierten en las dos formas de sintaxis diferentes, así que téngalo en cuenta.

Usando LIMIT...OFFSET no es muy eficiente cuando solicita una página que tiene muchas páginas en el resultado. Digamos que solicita la página 5000. MySQL tiene que generar un resultado en el lado del servidor de 5000 páginas, luego descartar 4999 de ellas y devolver la última página en el resultado. Lo siento, pero así es como funciona.

Re tu comentario:

Debes entender que WHERE aplica condiciones en valores en filas, pero las páginas están definidas por la posición de filas ¡Estas son dos formas diferentes de determinar las filas!

Si tiene una columna que se garantiza que es un número de fila , entonces puede usar ese valor como una posición de fila. Incluso puede ponerle un índice o usarlo como clave principal.

Pero los valores de la clave principal pueden cambiar y no ser consecutivos, por ejemplo, si actualiza o elimina filas, o revierte algunas transacciones, etc. Volver a numerar los valores de clave principal es una mala idea porque otras tablas o datos externos pueden hacer referencia a valores de clave principal.

Por lo tanto, podría agregar otra columna que no la clave principal, pero solo un número de fila.

ALTER TABLE MyTable ADD COLUMN row_number BIGINT UNSIGNED, ADD KEY (row_number);

Luego complete los valores cuando necesite volver a numerar las filas.

SET @row := 0;
UPDATE MyTable SET row_number = (@row := @row + 1) ORDER BY id;

Tendría que volver a numerar las filas si alguna vez elimina algunas, por ejemplo. No es eficiente hacer esto con frecuencia, dependiendo del tamaño de la mesa.

Además, las nuevas inserciones no pueden crear valores de número de fila correctos sin bloquear la tabla. Esto es necesario para evitar condiciones de carrera.

Si tiene una garantía de que row_number es una secuencia de valores consecutivos, entonces es tanto un valor como una posición de fila, por lo que puede usarlo para búsquedas de índice de alto rendimiento para cualquier página arbitraria de filas.

SELECT * FROM MyTable WHERE row_number BETWEEN 401 AND 500;

Al menos hasta la próxima vez que la secuencia de números de fila se ponga en duda por una eliminación o por nuevas inserciones.