mysql> select SQL_CALC_FOUND_ROWS * FROM tbl_name -> WHERE id > 100 LIMIT 10;
mysql> select FOUND_ROWS();
使用SQL_CALC_FOUND_ROWS能够在查询时为您事先准备好符合where条件的记录数目,然后只要在随后执行一句select FOUND_ROWS();
就能获得总记录数。
这个方法有一个副作用,当使用了SQL_CALC_FOUND_ROWS以后,将不能使用查询缓存、在特殊情况下反而或损失一些性能。
例如,一个文章表,所有文章做了主键ID,并做了CREATE_TIME DESC的索引。这样在执行
SELECT * FROM ARTICLE ORDER BY ID DESC LIMIT 10 或者 CREATE_TIME DESC LIMIT 20 时,数据库引擎可
以完全根据索引返回最新文章而不会管你有多少符合的记录,但用了SQL_CALC_FOUND_ROWS后引擎不得不扫描全表以确定全部记录数。
但无论怎样,这个 SQL_CALC_FOUND_ROWS 非常适合where字句异常复杂耗时的情况。在频繁使用查询的应用中,这个方法能够带
来1/3的数据库性能提升。
Never, never use SQL_CALC_FOUND_ROWS it’s just equally slow then “SELECT COUNT(*) FROM table”, but you have to do
it on every page. The count(*) variant you can cache at last, so you don’t have to do it on every page.
(用SQL_CALC_FOUND_ROWS 每页每次查询都会做Count;用 count(*),则可以自己缓存结果)
And there’s even another way to avoid the count on paging. It’s the way Facebook does paging on some places.
Facebook don’t give you the usually list of pages from 1 to n there, were you can click at any page. They just give
you the page before, the current page and the next page, if there’s one. On the application side it’s very easy to
find out if you have a page before the current, when you are on the second page there’s one before (so no surprise
here). But what about the next page if you don’t want to make a count. Easy stuff, let me predict you display 10
items per page, so query 11 items instead of 10 per page. This one extra item will cost you nearly nothing and now
you can count the returned rows in your application. If you have more than ten rows you have a next page and you can
happily throw number eleven away.
(只显示上下页;程序很容易知道有没有上一页;判断下一页,只需要多查询1条,则可以判断有没有下一条记录了。)