Cuando limita el número de filas que devuelve una consulta SQL, generalmente utilizada en la paginación, hay dos métodos para determinar el número total de registros:
Método 1
Incluya la SQL_CALC_FOUND_ROWS
opción en el original SELECT
y luego obtenga el número total de filas ejecutando SELECT FOUND_ROWS()
:
SELECT SQL_CALC_FOUND_ROWS * FROM table WHERE id > 100 LIMIT 10;
SELECT FOUND_ROWS();
Método 2
Ejecute la consulta normalmente y luego obtenga el número total de filas ejecutando SELECT COUNT(*)
SELECT * FROM table WHERE id > 100 LIMIT 10;
SELECT COUNT(*) FROM table WHERE id > 100;
¿Qué método es el mejor / más rápido?
fuente
SQL_CALC_FOUND_ROWS
tomó más de 20 segundos; el uso de unaCOUNT(*)
consulta separada tomó menos de 5 segundos (para ambas consultas de conteo + resultados).SQL_CALC_FOUND_ROWS
será más rápido, ¡me pregunto en qué situaciones (si las hay) en realidad es más rápido!tblA
,tblB
,tblC
,tblD
,tblY
DONDE tblA.b = tblC.id AND tblA.c = tblB.id AND tblA.d = tblD.id AND tblA.y = tblY.idid
) tomó 0.25 solo.FOUND_ROWS()
ha quedado en desuso en MySQL 8.0.17. Ver también la respuesta de @ madhur-bhaiya.Al elegir el "mejor" enfoque, una consideración más importante que la velocidad podría ser el mantenimiento y la corrección de su código. Si es así, es preferible SQL_CALC_FOUND_ROWS porque solo necesita mantener una sola consulta. El uso de una sola consulta excluye por completo la posibilidad de una sutil diferencia entre las consultas principales y de conteo, lo que puede conducir a un recuento inexacto.
fuente
MySQL ha comenzado a despreciar
SQL_CALC_FOUND_ROWS
funcionalidad con la versión 8.0.17 en adelante.Por lo tanto, siempre es preferible considerar ejecutar su consulta con
LIMIT
, y luego una segunda consulta conCOUNT(*)
y sinLIMIT
determinar si hay filas adicionales.De documentos :
Además,
SQL_CALC_FOUND_ROWS
se ha observado que tiene más problemas en general, como se explica en MySQL WL # 12615 :fuente
LOCK TABLES <tablename>
yUNLOCK TABLES
. La tercera opción y (mejor en mi humilde opinión) es repensar la paginación. Lea: mariadb.com/kb/en/library/pagination-optimizationSegún el siguiente artículo: https://www.percona.com/blog/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/
Si tiene un ÍNDICE en su cláusula where (si la identificación está indexada en su caso), entonces es mejor no usar SQL_CALC_FOUND_ROWS y usar 2 consultas en su lugar, pero si no tiene un índice de lo que puso en su cláusula where (id en su caso), entonces usar SQL_CALC_FOUND_ROWS es más eficiente.
fuente
En mi humilde opinión, la razón por la que 2 consultas
son más rápidos que usar SQL_CALC_FOUND_ROWS
tiene que ser visto como un caso particular.
De hecho, depende de la selectividad de la cláusula WHERE en comparación con la selectividad del implícito equivalente al ORDEN + LÍMITE.
Como Arvids dijo en un comentario ( http://www.mysqlperformanceblog.com/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/#comment-1174394 ), el hecho de que EXPLAIN usa o no, una tabla de temporay, debería ser una buena base para saber si SCFR será más rápido o no.
Pero, como agregué ( http://www.mysqlperformanceblog.com/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/#comment-8166482 ), el resultado realmente depende del caso. Para un paginador en particular, puede llegar a la conclusión de que “para las 3 primeras páginas, use 2 consultas; para las siguientes páginas, use un SCFR ”!
fuente
Eliminar algunos SQL innecesarios y luego
COUNT(*)
será más rápido queSQL_CALC_FOUND_ROWS
. Ejemplo:Luego cuente sin parte innecesaria:
fuente
Hay otras opciones para que pueda comparar:
1.) Una función de ventana devolverá el tamaño real directamente (probado en MariaDB):
2.) Pensando fuera de la caja, la mayoría de las veces los usuarios no necesitan saber el tamaño EXACTO de la tabla, un aproximado suele ser lo suficientemente bueno.
fuente