分页程序一般由两条SQL组成:

SELECT COUNT(*) FROM ... WHERE ....
SELECT ... FROM ... WHERE LIMIT ...

  如果使用SQL_CALC_FOUND_ROWS的话,一条SQL就可以了:

SELECT SQL_CALC_FOUND_ROWS ... FROM ... WHERE LIMIT ...

  在得到数据后,通过FOUND_ROWS()可以得到不带LIMIT的结果数:

SELECT FOUND_ROWS()

  看上去,似乎SQL_CALC_FOUND_ROWS应该快于COUNT(*),但实际情况并不是这样简单,请看:

  To SQL_CALC_FOUND_ROWS or not to SQL_CALC_FOUND_ROWS?

  用数据说话,证明了COUNT(*)相对SQL_CALC_FOUND_ROWS来说更快。不过我觉得这个结论也不全面,某些情况下,SQL_CALC_FOUND_ROWS更有优势,看我的实验:

  表结构如下:


CREATE TABLE IF NOT EXISTS `foo` (
`a` int(10) unsigned NOT NULL AUTO_INCREMENT,
`b` int(10) unsigned NOT NULL,
`c` varchar(100) NOT NULL,
PRIMARY KEY (`a`),
KEY `bar` (`b`,`a`)
) ENGINE=MyISAM;

  导入一些测试数据:

for ($i = 0; $i <10000; $i++) {
mysql_query("INSERT INTO foo SET b=ROUND(RAND()*10), c=MD5({$i})");
}

  先测试COUNT(*)方式:


$start = microtime(true);
for ($i = 0; $i < 1000; $i++) {
mysql_query("SELECT SQL_NO_CACHE COUNT(*) FROM foo WHERE b = 1");
mysql_query("SELECT SQL_NO_CACHE a FROM foo WHERE b = 1 LIMIT 100, 10");
}
$end = microtime(true);
echo $end - $start;

  结果输出(数据大小视测试机性能而定):0.75777006149292

  再测试SQL_CALC_FOUND_ROWS方式:


$start = microtime(true);
for ($i = 0; $i < 1000; $i++) {
mysql_query("SELECT SQL_NO_CACHE SQL_CALC_FOUND_ROWS a FROM foo WHERE b = 1 LIMIT 100, 10");
mysql_query("SELECT FOUND_ROWS()");
}
$end = microtime(true);
echo $end - $start;

  结果输出(数据大小视测试机性能而定):0.6681969165802

  有数据有真相,那为什么我的实验结论和MySQL Performance Blog的结论相悖呢?这是因为在MySQL Performance Blog的实验里,COUNT(*)查询是执行的的Covering Index,而SQL_CALC_FOUND_ROWS是执行的表查询;而在我的实验里,因为我定义了适当的索引,COUNT(*)和SQL_CALC_FOUND_ROWS都是执行的Covering Index,所以结论出现了差异。

  既然使用了Covering Index,就意味着不能再使用SELECT *的形式了,只能使用类似SELECT id这样的形式了,用的列在索引里都能查到,如此说来,我们需要的实际数据从哪来呢?这个很简单,有了主键之后,实际数据可以通过Key/Value形式的缓存获得,这样的架构很常见。

  结论:SQL_CALC_FOUND_ROWS如果执行的是Covering Index的话,是很快的!换个角度看,如果COUNT(*)和SQL_CALC_FOUND_ROWS都只能通过表查询来检索,那么分页时,SQL_CALC_FOUND_ROWS同样会快于COUNT(*),读者可自行测试。

http://kb.cnblogs.com/page/82986/

SQL_CALC_FOUND_ROWS。
SELECT SQL_CALC_FOUND_ROWS ... FROM ... WHERE LIMIT ...
所谓SQL_CALC_FOUND_ROWS是指在执行带LIMIT的查询时,附带统计一下如果不加LIMIT的话将会输出多少条结果。

在得到数据后,通过FOUND_ROWS()可以得到不带LIMIT的结果数:
SELECT FOUND_ROWS()

MySQL的SQL_CALC_FOUND_ROWS真的很慢么?的更多相关文章

  1. MySQL开发篇,存储引擎的选择真的很重要吗?

    前言 谁说MySQL查询千万级别的数据很拉跨?我今天就要好好的和你拉拉家常,畅谈到深夜,一起过除夕!这篇文章也是年前的最后一篇,希望能带给大家些许收获,不知不觉查找文档和参考实体书籍就写了这么多,自己 ...

  2. 值得推荐的C/C++框架和库 (真的很强大) c

    http://m.blog.csdn.net/mfcing/article/details/49001887 值得推荐的C/C++框架和库 (真的很强大) 发表于2015/10/9 21:13:14 ...

  3. 转-MySQL教程-写的很详细,赞一个

    原帖地址:https://www.w3cschool.cn/mysql/,谢谢原帖大人 MySQL是什么? MySQL安装 MySQL示例数据库 MySQL导入示例数据库 MySQL基础教程 MySQ ...

  4. mysql的SQL_CALC_FOUND_ROWS 使用 类似count(*) 使用性能更高

    mysql的SQL_CALC_FOUND_ROWS 使用 类似count(*) 使用性能更高 在很多分页的程序中都这样写: SELECT COUNT(*) from `table` WHERE ... ...

  5. 【转】 值得推荐的C/C++框架和库 (真的很强大)

    [转] 值得推荐的C/C++框架和库 (真的很强大) 值得学习的C语言开源项目 - 1. Webbench Webbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个 ...

  6. MYSQL的SQL_CALC_FOUND_ROWS 和count(*)

    mysql的SQL_CALC_FOUND_ROWS 和 count(*) 在很多分页的程序中都这样写: SELECT COUNT(*) from `table` WHERE ......;  查出符合 ...

  7. HTTP真的很简单

    原文:HTTP Made Really Easy因为我本身网络基础就很差,所以看到这篇文章一方面是学习网络知识,另一方面为了锻炼我蹩脚的英语水平,文中如有错误,欢迎浏览指正! 前言 在看这篇文章的时候 ...

  8. paip.解决 数据库mysql增加列 字段很慢添加字段很慢

    paip.解决 数据库mysql增加列 字段很慢添加字段很慢 #环境如下: mysql5.6    数据仅仅3w alter table xxx add column yyy int default ...

  9. 转:Eric Lippert:阅读代码真的很难

    转自:http://blog.jobbole.com/438/ 相关文章 微软资深软件工程师:阅读代码真的很难(第2篇) 阅读优秀代码是提高开发人员修为的一种捷径 学会阅读源代码 如何阅读大型代码库? ...

随机推荐

  1. HDU_2039——判断三条边是否能组成三角形

    Problem Description 给定三条边,请你判断一下能不能组成一个三角形.   Input 输入数据第一行包含一个数M,接下有M行,每行一个实例,包含三个正数A,B,C.其中A,B,C & ...

  2. 电脑上已经安装mysql之后安装wamp,wamp中的mysql无法启动的解决办法

    Wampserver安装完成后无法启动MySQL这有可能是你之前安装过MysqL,因为wampserver内置MySQL.解决的方法就是配置环境变量. 找到我的电脑或计算机右键,打开属性,然后打开高级 ...

  3. C#request 请求响应

    /// <summary> /// 提交POST请求 /// </summary> /// <param name="url">提交地址< ...

  4. Java随机数生产算法

    java提供了Math.random()函数,返回一个double类型的随机数,也有util包里的Random类,可以生成double,int,float,long,bytes等随机数. 但有些业务需 ...

  5. poj 1089 Intervals

    http://poj.org/problem?id=1089 Intervals Time Limit: 1000MS   Memory Limit: 10000K Total Submissions ...

  6. 正则表达式:网页爬虫:从TXT中获取邮箱地址(获取的练习,缺点:一行只能匹配一个)

    import java.util.regex.*; import java.io.*; class L { public static void main(String[] args) throws  ...

  7. 大学生程序猿IT情书“2014爱的告白挑战赛”获奖名单及优秀情书展示系列之 - 【IT术语】情书+【搞笑另类】情书

    经过专家评委们的层层精心评选和认真讨论,恭喜下面同学终于入选CSDN高校俱乐部"大学生程序猿IT情书2014爱的告白挑战赛活动"优胜者名单.获奖者将在本周内收到邮件通知.请依照邮件 ...

  8. 你的第一Windows程序——管理应用程序状态

    MSDN原文(英文) 管理应用程序状态 一个窗口过程仅仅是一个为每个消息获取调用函数,所以它本质上是无状态的.因此,你需要一个方法来跟踪你的应用程序从一个函数调用下一个函数的状态. 最简单的方法是把一 ...

  9. LSI SAS 3008配置操作

    配置 LSI SAS 3008 介绍LSISAS3008的配置操作. 4.1 登录CU界面 介绍登录LSISAS3008的CU配置界面的方法. 4.2 创建RAID 介绍在LSISAS3008扣卡上创 ...

  10. iOS_SN_UITableView的优化

    1.提前计算并缓存好高度(布局),因为heightForRowAtIndexPath:是调用最频繁的方法. 2.异步绘制,遇到复杂界面,遇到性能瓶颈时,可能就是突破口. 3.滑动时按需加载,这个在大量 ...