哪个最快? SELECT SQL_CALC_FOUND_ROWS FROM`table`,或SELECT COUNT(*)

当限制通常用于分页的SQL查询返回的行数时,有两种方法可以确定总logging数:

方法1

在原始SELECT包含SQL_CALC_FOUND_ROWS选项,然后通过运行SELECT FOUND_ROWS()获取总行数:

 SELECT SQL_CALC_FOUND_ROWS * FROM table WHERE id > 100 LIMIT 10; SELECT FOUND_ROWS(); 

方法2

正常运行查询,然后通过运行SELECT COUNT(*)获取总行数

 SELECT * FROM table WHERE id > 100 LIMIT 10; SELECT COUNT(*) FROM table WHERE id > 100; 

哪种方法是最好的/最快的?

这取决于。 查看关于这个主题的MySQL性能博客文章: http : //www.mysqlperformanceblog.com/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/

只是一个简单的总结:彼得说,这取决于你的指标和其他因素。 对这个post的许多评论似乎都说SQL_CALC_FOUND_ROWS几乎总是比较慢 – 有时比速度慢10倍 – 比运行两个查询要慢。

当select“最佳”方法时,比速度更重要的考虑因素可能是代码的可维护性和正确性。 如果是这样,SQL_CALC_FOUND_ROWS是最好的,因为你只需要维护一个单一的查询。 使用单个查询完全排除了主查询和计数查询之间细微差异的可能性,这可能导致COUNT不准确。

根据以下文章: https : //www.percona.com/blog/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/

如果你的where子句有一个INDEX (如果id是你的情况的索引),那么最好不要使用SQL_CALC_FOUND_ROWS ,而是使用2个查询,但是如果你没有在你的where子句中放置什么的索引(id在你的情况),那么使用SQL_CALC_FOUND_ROWS更有效率。

恕我直言,之所以2查询

 SELECT * FROM count_test WHERE b = 666 ORDER BY c LIMIT 5; SELECT count(*) FROM count_test WHERE b = 666; 

比使用SQL_CALC_FOUND_ROWS更快

 SELECT SQL_CALC_FOUND_ROWS * FROM count_test WHERE b = 555 ORDER BY c LIMIT 5; 

必须被看作是一个特例。

它实际上取决于WHERE子句的select性,与隐式ORDER + LIMIT的select性相比。

正如Arvids在评论中所说( http://www.mysqlperformanceblog.com/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/#comment-1174394),EXPLAIN使用或不使用的事实,一个临时表,应该是知道SCFR是否会更快的好基础。;

但是,正如我添加( http://www.mysqlperformanceblog.com/2007/08/28/to-sql_calc_found_rows-or-not-to-sql_calc_found_rows/#comment-8166482 ),结果真的,取决于案件。 对于一个特定的分页器,你可以得出这样的结论:“对于前3页,使用2个查询; 对于以下页面,使用SCFR“!

删除一些不必要的SQL,然后COUNT(*)将比SQL_CALC_FOUND_ROWS更快。 例:

  • 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

然后算没有不必要的部分:

  • 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