MySQL Data - ¿La mejor manera de implementar paginación?


Mi aplicación para iPhone se conecta a mi servicio web PHP para recuperar datos de una base de datos MySQL. Una solicitud puede devolver 500 resultados.

¿Cuál es la mejor manera de implementar la paginación y recuperar 20 elementos a la vez?

Digamos que recibo los primeros 20 anuncios de mi base de datos. Ahora, ¿cómo puedo solicitar los próximos 20 anuncios?

 146
Author: Pang, 2010-09-26

7 answers

De la documentación de MySQL :

La cláusula LIMIT se puede usar para restringir el número de filas devueltas por la instrucción SELECT. LIMIT toma uno o dos argumentos numéricos, que deben ser constantes enteras no negativas (excepto cuando se usan sentencias preparadas).

Con dos argumentos, el primer argumento especifica el desplazamiento de la primera fila a devolver, y el segundo especifica el número máximo de filas a devolver. El desplazamiento de la fila inicial es 0 (no 1):

SELECT * FROM tbl LIMIT 5,10;  # Retrieve rows 6-15

Para recuperar todas las filas desde un cierto desplazamiento hasta el final del conjunto de resultados, puede usar un número grande para el segundo parámetro. Esta instrucción recupera todas las filas desde la fila 96 hasta la última:

SELECT * FROM tbl LIMIT 95,18446744073709551615;

Con un argumento, el valor especifica el número de filas a devolver desde el principio del conjunto de resultados:

SELECT * FROM tbl LIMIT 5;     # Retrieve first 5 rows

En otras palabras, LIMIT row_count es equivalente a LIMIT 0, row_count.

 229
Author: Faisal Feroz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-02 07:55:12

Para 500 registros la eficiencia probablemente no sea un problema, pero si tiene millones de registros, puede ser ventajoso usar una cláusula WHERE para seleccionar la siguiente página:

SELECT *
FROM yourtable
WHERE id > 234374
ORDER BY id
LIMIT 20

El "234374" aquí es el id del último registro de la página anterior que vio.

Esto permitirá que se use un índice en id para encontrar el primer registro. Si utilizas LIMIT offset, 20 podrías encontrar que se vuelve más y más lento a medida que navegas hacia el final. Como dije, probablemente no importará si solo tienes 200 registros, pero puede hacer una diferencia con conjuntos de resultados más grandes.

Otra ventaja de este enfoque es que si los datos cambian entre las llamadas, no perderá registros ni obtendrá un registro repetido. Esto se debe a que agregar o eliminar una fila significa que el desplazamiento de todas las filas después de que cambia. En su caso, probablemente no es importante, supongo que su grupo de anuncios no cambia demasiado a menudo y, de todos modos, nadie se daría cuenta si reciben el mismo anuncio dos veces seguidas, pero si está buscando la" mejor manera " entonces esto es otra cosa a tener en cuenta al elegir qué enfoque usar.

Si desea usar LIMIT con un offset (y esto es necesario si un usuario navega directamente a la página 10000 en lugar de paginar a través de páginas una por una), entonces puede leer este artículo sobre búsquedas finales de filas para mejorar el rendimiento de LIMIT con un offset grande.

 86
Author: Mark Byers,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-26 19:20:07

Hay literatura al respecto:

El principal problema ocurre con el uso de grandes OFFSETs. Evitan usar OFFSET con una variedad de técnicas, que van desde las selecciones de rango id en la cláusula WHERE, hasta algún tipo de almacenamiento en caché o páginas pre-computacionales.

Hay soluciones sugeridas en Use el ÍNDICE, Lucas :

 15
Author: Luchostein,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-09 23:39:17

Define OFFSET para la consulta. Por ejemplo

Página 1 - (registros 01-10): offset = 0, limit = 10;

Página 2 - (registros 11-20) desplazamiento = 10, límite = 10;

Y utilice la siguiente consulta :

SELECT column FROM table LIMIT {someLimit} OFFSET {someOffset};

Ejemplo para la página 2:

SELECT column FROM table
LIMIT 10 OFFSET 10;
 13
Author: Prabodh Hend,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-28 06:22:23

Este tutorial muestra una gran manera de hacer paginación. Paginación eficiente Usando MySQL

En resumen, evite usar DESPLAZAMIENTO o LÍMITE grande

 11
Author: Bao Le,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-11 06:27:33

También puedes hacer

SELECT SQL_CALC_FOUND_ROWS * FROM tbl limit 0, 20

El recuento de filas de la instrucción select (sin el límite) se captura en la misma instrucción select, de modo que no es necesario volver a consultar el tamaño de la tabla. Se obtiene el recuento de filas usando SELECT FOUND_ROWS ();

 4
Author: surajz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-26 18:48:35

Consulta 1: SELECT * FROM yourtable WHERE id > 0 ORDER BY id LIMIT 500

Consulta 2: SELECT * FROM tbl LIMIT 0,500;

La consulta 1 se ejecuta más rápido con registros pequeños o medianos, si el número de registros es igual a 5,000 o superior, el resultado es similar.

Resultado para 500 registros:

Query1 take 9.9999904632568 milisegundos

Query2 take 19.999980926514 milisegundos

Resultado para 8.000 registros:

Query1 take 129.99987602234 milisegundos

Query2 toma 160.00008583069 milisegundos

 2
Author: Huy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-23 09:14:37