¿Cuál es el más rápido? SELECCIONE SQL CALC FOUND ROWS DE 'table', o SELECCIONE COUNT(*)
Cuando se limita el número de filas que debe devolver una consulta SQL, generalmente utilizada en paginación, hay dos métodos para determinar el número total de registros:
Método 1
Incluya la opción SQL_CALC_FOUND_ROWS
en el SELECT
original, 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?
5 answers
Depende. Vea la publicación del Blog sobre Rendimiento de MySQL sobre este tema: http://www.mysqlperformanceblog.com/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/
Solo un breve resumen: Peter dice que depende de sus índices y otros factores. Muchos de los comentarios a la publicación parecen decir que SQL_CALC_FOUND_ROWS es casi siempre más lento-a veces hasta 10 veces más lento-que ejecutar dos consultas.
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
2008-10-09 19:09:00
Al elegir el enfoque "mejor", una consideración más importante que la velocidad podría ser la capacidad de mantenimiento y la corrección de su código. Si es así, SQL_CALC_FOUND_ROWS es preferible porque solo necesita mantener una sola consulta. El uso de una única consulta excluye completamente la posibilidad de una diferencia sutil entre las consultas main y count, lo que puede conducir a un RECUENTO inexacto.
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-19 18:19:05
Segú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 INDEX en su cláusula where (si id está indexado 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 pone en su cláusula where (id en su caso), entonces usar SQL_CALC_FOUND_ROWS es más eficiente.
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-06-22 14:54:16
EN mi humilde opinión, la razón por la que 2 consultas
SELECT * FROM count_test WHERE b = 666 ORDER BY c LIMIT 5;
SELECT count(*) FROM count_test WHERE b = 666;
Son más rápidos que usar SQL_CALC_FOUND_ROWS
SELECT SQL_CALC_FOUND_ROWS * FROM count_test WHERE b = 555 ORDER BY c LIMIT 5;
Tiene que ser visto como un caso particular.
En los hechos depende de la selectividad de la cláusula WHERE en comparación con la selectividad de la implícita equivalente a la ORDEN + LÍMITE.
Como Arvids dijo en 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 el EXPLICAR el uso, o no, de una tabla temporay, debería ser una buena base para saber si el SCFR será más rápido o no.
Pero, como he añadido (http://www.mysqlperformanceblog.com/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/#comment-8166482)el resultado realmente, realmente depende del caso. Para un paginador en particular, se podría llegar a la conclusión de que "para las 3 primeras páginas, utilice 2 consultas; para las páginas siguientes, utilice un SCFR" !
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
2014-08-04 17:36:26
Eliminar algunos SQL innecesarios y luego COUNT(*)
será más rápido que SQL_CALC_FOUND_ROWS
. Ejemplo:
-
SELECT Person.Id, Person.Name, Job.Description, Card.Number
-
FROM Person
-
JOIN Job ON Job.Id = Person.Job_Id
-
LEFT JOIN Card ON Card.Person_Id = Person.Id
-
WHERE Job.Name = 'WEB Developer'
ORDER BY Person.Name
Luego cuente sin parte innecesaria:
SELECT COUNT(*)
FROM Person
JOIN Job ON Job.Id = Person.Job_Id
LEFT JOIN Card ON Card.Person_Id = Person.Id
WHERE Job.Name = 'WEB Developer'
ORDER BY Person.Name
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-04-07 19:53:39