¿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?

Author: cmbuckley, 2008-10-09

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.

 105
Author: nathan,
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.

 16
Author: Jeff Clemens,
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.

 10
Author: patapouf_ai,
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" !

 7
Author: Pierre-Olivier Vares,
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
 2
Author: Jessé Catrinck,
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