2009-09-01 15 views
6

Como algunos de ustedes saben, el uso de la palabra clave LIMIT en MySQL no impide que lea los registros anteriores.¿Cómo paginar eficientemente grandes conjuntos de datos con PHP y MySQL?

Por ejemplo:

SELECT * FROM my_table LIMIT 10000, 20; 

Significa que todavía MySQL leerá los primeros 10.000 registros y tirar a la basura antes de producir el 20 que estamos buscando.

Por lo tanto, al paginar un conjunto de datos grande, los números de página altos significan tiempos de carga largos.

¿Alguien conoce alguna clase/técnica/metodología de paginación existente que pueda paginar grandes conjuntos de datos de una manera más eficiente, es decir, que no se base en la palabra clave LIMIT MySQL?

En PHP, si es posible, ya que es el arma de elección en mi empresa.

Saludos.

+2

Si su conjunto de datos no es probable que cambie, puede calcular el índice de página para cada elemento en el fondo y, a continuación, la paginación solo se convierte en una selección en un campo indexado. lo que podría pasar es que accidentalmente tendrá n + 1 elementos en una página ocasionalmente. – Zed

+2

http://stackoverflow.com/questions/1243952/how-can-i-speed-up-a-mysql-query-with-a-large-offset-in-the-limit-clause – Sampson

Respuesta

1

Una solución podría ser no usar la cláusula de límite, y usar una unión en su lugar, unir en una tabla utilizada como un tipo de secuencia.

Para más informaciones, por lo tanto, yo encontraron esta question/answer, lo que da un ejemplo - que podría ayudarle a ;-)

+1

¡Gracias amigo, voy a echar un vistazo! – Evernoob

0

No conozco la disminución de rendimiento que ha mencionado, y no conozco ninguna otra solución para la paginación; sin embargo, una cláusula ORDER BY puede ayudarlo a reducir el tiempo de carga.

0

La mejor manera es definir el campo de índice en my_table y para cada nueva fila insertada necesita incrementar este campo. Y, después de todo, debe usar WHERE YOUR_INDEX_FIELD ENTRE 10000 Y 10020 Será mucho más rápido.

+1

Esto requiere que nunca elimine todas las filas y no muestre agregados. – nos

1

Básicamente, hay 3 métodos para esto, cada uno de los cuales tienen sus propias ventajas y desventajas :

  1. Envíe los 10000 registros al cliente y maneje la paginación del lado del cliente a través de Javascript o similar. El beneficio obvio es que solo una consulta es necesaria para todos los registros; La desventaja obvia es que, si el tamaño del registro es significativo, el tamaño de la página enviada al navegador será de tamaño proporcionado, y el usuario podría no preocuparse por el conjunto completo de registros.

  2. Haga lo que está haciendo actualmente, a saber, SQL LIMIT y obtenga solo los registros que necesita con cada solicitud, completamente sin estado. Se beneficia porque solo envía los registros de la página solicitada actualmente, por lo que las solicitudes son pequeñas, inconvenientes en que a) requiere una solicitud del servidor para cada página, yb) es más lenta a medida que aumenta el número de registros/páginas para páginas posteriores en el resultado, como lo mencionaste. El uso de una cláusula JOIN o WHERE en un campo de identificación monótonamente creciente a veces puede ser útil en este sentido, especialmente si está solicitando resultados de una tabla estática en lugar de una consulta dinámica.

  3. Mantener algún tipo de objeto de estado en el servidor que almacena en caché los resultados de la consulta y se puede hacer referencia en futuras solicitudes por un período de tiempo limitado. Al revés es que tiene la mejor velocidad de consulta, ya que la consulta real solo necesita ejecutarse una vez; La desventaja es tener que administrar/almacenar/limpiar esos objetos de estado (especialmente desagradable para sitios web de alto tráfico).

0

algunas otras opciones,

  • partición de las tablas por cada página así que ignore el límite
  • tienda los resultados en una sesión (una buena idea sería crear un hash de los datos utilizando md5, luego usar esa memoria caché la sesión por usuarios múltiples)
+0

no es realmente un fan de almacenar un conjunto de datos tan grande en una sesión – Evernoob

6

En primer lugar, si desea paginar, absolutamente debe tener una cláusula ORDER BY. Entonces, simplemente tiene que usar esa cláusula para profundizar en su conjunto de datos. Por ejemplo, considere esto:

SELECT * FROM my_table ORDER BY id LIMIT 20 

Vas a tener los primeros 20 registros, digamos que sus identificadores son: 5,8,9, ..., 55,64. Su enlace de paginación a la página 2 se verá como "list.php? Page = 2 & id = 64" y la consulta será

SELECT * FROM my_table WHERE id > 64 ORDER BY id LIMIT 20 

Sin desplazamiento, a sólo 20 registros leídos. No le permite saltar arbitrariamente a ninguna página, pero la mayoría de las veces las personas simplemente navegan por la página siguiente/anterior. Un índice en "id" mejorará el rendimiento, incluso con grandes valores de OFFSET.

+0

Lo único que no se tiene en cuenta son las filas eliminadas (supone una numeración constante para los identificadores) ... –

+0

Es una buena idea, pero sí yo también Necesito los números de página, lo que significa que tendría que a) a) nunca eliminar ninguna fila ob) calcular y almacenar en alguna parte los identificadores de cada registro que finaliza cada página. – Evernoob

+0

si no obtiene suficientes filas, solo solicite algunas más. sigue solicitando por lotes hasta que obtengas suficiente o obtienes 0 (lo que significa que no hay más filas). asegúrese de hacer un seguimiento de dónde está el final real para que el siguiente conjunto de filas sea contiguo con lo que se mostró al usuario, no con lo que se recuperó. – longneck

1
SELECT * FROM my_table LIMIT 10000, 20; 

medios muestran 20 registros a partir de registro # 10000 en la búsqueda, si ur utilizando claves primarias en la cláusula where no habrá una carga pesada en mi sql

cualquier otro método para pagnation tendrá carga enorme real como usar un método de combinación

Cuestiones relacionadas