Me preguntaba si había una manera de obtener el número de resultados de una consulta MySQL y, al mismo tiempo, limitar los resultados.
La forma en que funciona la paginación (según tengo entendido), primero hago algo como
query = SELECT COUNT(*) FROM `table` WHERE `some_condition`
Después de obtener num_rows (consulta), tengo el número de resultados. Pero luego, para limitar realmente mis resultados, tengo que hacer una segunda consulta como:
query2 = SELECT COUNT(*) FROM `table` WHERE `some_condition` LIMIT 0, 10
Mi pregunta: ¿Hay alguna forma de recuperar el número total de resultados que se darían y limitar los resultados devueltos en una sola consulta? O cualquier forma más eficiente de hacer esto. ¡Gracias!
mysql
pagination
double
atp
fuente
fuente
Respuestas:
No, esa es la cantidad de aplicaciones que quieran paginar tienen que hacerlo. Es confiable y a prueba de balas, aunque hace la consulta dos veces. Pero puede almacenar en caché el recuento durante unos segundos y eso ayudará mucho.
La otra forma es usar
SQL_CALC_FOUND_ROWS
cláusula y luego llamarSELECT FOUND_ROWS()
. Aparte del hecho de que tienes que poner laFOUND_ROWS()
llamada después, hay un problema con esto: hay un error en MySQL que hace cosquillas que afecta lasORDER BY
consultas haciéndolo mucho más lento en tablas grandes que el enfoque ingenuo de dos consultas.fuente
Casi nunca hago dos consultas.
Simplemente devuelva una fila más de la necesaria, solo muestre 10 en la página, y si hay más de las que se muestran, muestre un botón "Siguiente".
Su consulta debe aparecer en el orden más relevante primero. Lo más probable es que a la mayoría de las personas no les importe ir a la página 236 de 412.
Cuando realiza una búsqueda en Google y sus resultados no están en la primera página, es probable que vaya a la página dos, no a la nueve.
fuente
COUNT
es una función agregada. ¿Cómo devuelve el recuento y todos los resultados en una consulta? La consulta anterior solo devolverá 1 fila, sin importar en quéLIMIT
se establezca. Si agregaGROUP BY
, devolverá todos los resultados, peroCOUNT
serán inexactosOtro enfoque para evitar la doble consulta es buscar todas las filas de la página actual usando primero una cláusula LIMIT, luego solo hacer una segunda consulta COUNT (*) si se recuperó el número máximo de filas.
En muchas aplicaciones, el resultado más probable será que todos los resultados quepan en una página y tener que hacer la paginación es la excepción y no la norma. En estos casos, la primera consulta no recuperará el número máximo de resultados.
Por ejemplo, las respuestas a una pregunta de stackoverflow rara vez se extienden a una segunda página. Los comentarios sobre una respuesta rara vez superan el límite de 5 o más necesarios para mostrarlos todos.
Entonces, en estas aplicaciones, puede simplemente hacer una consulta con un LÍMITE primero, y luego, mientras no se alcance ese límite, sabrá exactamente cuántas filas hay sin la necesidad de hacer una segunda consulta COUNT (*), que debería cubre la mayoría de situaciones.
fuente
En la mayoría de las situaciones, es mucho más rápido y requiere menos recursos hacerlo en dos consultas separadas que hacerlo en una, aunque eso parezca contrario a la intuición.
Si usa SQL_CALC_FOUND_ROWS, entonces para tablas grandes hace que su consulta sea mucho más lenta, significativamente más lenta incluso que ejecutar dos consultas, la primera con COUNT (*) y la segunda con LIMIT. La razón de esto es que SQL_CALC_FOUND_ROWS hace que la cláusula LIMIT se aplique después de obtener las filas en lugar de antes, por lo que recupera la fila completa para todos los resultados posibles antes de aplicar los límites. Esto no puede ser satisfecho por un índice porque en realidad recupera los datos.
Si adopta el enfoque de dos consultas, la primera solo obtiene COUNT (*) y no obtiene datos reales, esto se puede satisfacer mucho más rápidamente porque generalmente puede usar índices y no tiene que obtener los datos de fila reales para cada fila que mira. Luego, la segunda consulta solo necesita mirar las primeras filas $ offset + $ limit y luego regresar.
Esta publicación del blog de rendimiento de MySQL explica esto con más detalle:
http://www.mysqlperformanceblog.com/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/
Para obtener más información sobre cómo optimizar la paginación, consulte esta publicación y esta publicación .
fuente
Mi respuesta puede llegar tarde, pero puede omitir la segunda consulta (con el límite) y simplemente filtrar la información a través de su script de back-end. En PHP, por ejemplo, podría hacer algo como:
Pero, por supuesto, cuando tiene que considerar miles de registros, se vuelve ineficaz muy rápido. El recuento precalculado puede ser una buena idea para analizar.
Aquí hay una buena lectura sobre el tema: http://www.percona.com/ppc2009/PPC2009_mysql_pagination.pdf
fuente
fuente
where
cláusula a la consulta interna y obtendrá el "total" correcto junto con los resultados paginados (la página está seleccionada con lalimit
cláusulaPara cualquiera que busque una respuesta en 2020. Según la documentación de MySQL:
"El modificador de consulta SQL_CALC_FOUND_ROWS y la función FOUND_ROWS () que lo acompaña están obsoletos a partir de MySQL 8.0.17 y se eliminarán en una versión futura de MySQL. Como reemplazo, considere ejecutar su consulta con LIMIT y luego una segunda consulta con COUNT (*) y sin LIMIT para determinar si hay filas adicionales ".
Supongo que eso soluciona eso.
https://dev.mysql.com/doc/refman/8.0/en/information-functions.html#function_found-rows
fuente
Puede reutilizar la mayor parte de la consulta en una subconsulta y establecerla en un identificador. Por ejemplo, una consulta de películas que busca películas que contengan las letras ordenadas por tiempo de ejecución se vería así en mi sitio.
Tenga en cuenta que no soy un experto en bases de datos y espero que alguien pueda optimizar eso un poco mejor. Tal como está, ejecutarlo directamente desde la interfaz de línea de comandos SQL, ambos toman ~ 0.02 segundos en mi computadora portátil.
fuente
fuente