MySQL的SQL_CALC_FOUND_ROWS真的很慢么?
分页程序一般由两条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真的很慢么?的更多相关文章
- MySQL开发篇,存储引擎的选择真的很重要吗?
前言 谁说MySQL查询千万级别的数据很拉跨?我今天就要好好的和你拉拉家常,畅谈到深夜,一起过除夕!这篇文章也是年前的最后一篇,希望能带给大家些许收获,不知不觉查找文档和参考实体书籍就写了这么多,自己 ...
- 值得推荐的C/C++框架和库 (真的很强大) c
http://m.blog.csdn.net/mfcing/article/details/49001887 值得推荐的C/C++框架和库 (真的很强大) 发表于2015/10/9 21:13:14 ...
- 转-MySQL教程-写的很详细,赞一个
原帖地址:https://www.w3cschool.cn/mysql/,谢谢原帖大人 MySQL是什么? MySQL安装 MySQL示例数据库 MySQL导入示例数据库 MySQL基础教程 MySQ ...
- mysql的SQL_CALC_FOUND_ROWS 使用 类似count(*) 使用性能更高
mysql的SQL_CALC_FOUND_ROWS 使用 类似count(*) 使用性能更高 在很多分页的程序中都这样写: SELECT COUNT(*) from `table` WHERE ... ...
- 【转】 值得推荐的C/C++框架和库 (真的很强大)
[转] 值得推荐的C/C++框架和库 (真的很强大) 值得学习的C语言开源项目 - 1. Webbench Webbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个 ...
- MYSQL的SQL_CALC_FOUND_ROWS 和count(*)
mysql的SQL_CALC_FOUND_ROWS 和 count(*) 在很多分页的程序中都这样写: SELECT COUNT(*) from `table` WHERE ......; 查出符合 ...
- HTTP真的很简单
原文:HTTP Made Really Easy因为我本身网络基础就很差,所以看到这篇文章一方面是学习网络知识,另一方面为了锻炼我蹩脚的英语水平,文中如有错误,欢迎浏览指正! 前言 在看这篇文章的时候 ...
- paip.解决 数据库mysql增加列 字段很慢添加字段很慢
paip.解决 数据库mysql增加列 字段很慢添加字段很慢 #环境如下: mysql5.6 数据仅仅3w alter table xxx add column yyy int default ...
- 转:Eric Lippert:阅读代码真的很难
转自:http://blog.jobbole.com/438/ 相关文章 微软资深软件工程师:阅读代码真的很难(第2篇) 阅读优秀代码是提高开发人员修为的一种捷径 学会阅读源代码 如何阅读大型代码库? ...
随机推荐
- HRBUST 1987 逃课的孩子
Sol:HASH + 二分 字符串处理,很基础的操作. 题意很明确就是找重复的次数统计下,范围比较大1≤n≤10000,1≤m≤10000. #include <cstdio> #inc ...
- Python操作Redis的5种数据类型
1.连接redis(两种方式) # decode_responses=True: 解决获取的值类型是bytes字节问题 r = redis.Redis(host=', db=0, decode_res ...
- 类型兼容原则(C++)
类型兼容原则是指在需要基类对象的任何地方,都可以使用公有派生类的对象来替代. 通过公有继承,派生类得到了基类中除构造函数.析构函数之外的所有成员.这样,公有派生类实际具备了基类的所有功能,凡是基类能解 ...
- hdu2209翻纸牌游戏
翻纸牌游戏 Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Subm ...
- 使用zTree控件制作的表格形式的树形+数据菜单
測试了一下,兼容ie7以上, chrome opera ff 不使用对方css /*------------------------------------- zTree Style version: ...
- Codeforces Round #FF (Div. 2):Problem A - DZY Loves Hash
A. DZY Loves Hash time limit per test 1 second memory limit per test 256 megabytes input standard in ...
- sys--system-sysdba-sysoper用户区别
当Oracle 数据库安装完毕后,系统会自动创建sys和system这两个帐户.1.sys :缺省密码为CHANGE_ON_INSTALL ,且被授予DBA角色system :缺省密码为MANAGER ...
- RecyclerView 详解
概述 RecyclerView出现已经有一段时间了,相信大家肯定不陌生了,大家可以通过导入support-v7对其进行使用. 据官方的介绍,该控件用于在有限的窗口中展示大量数据集,其实这样功能的控件 ...
- 3.2:pandas数据的导入与导出【CSV,JSON】
一:CSV数据 一]:导入数据 1)从CSV文件读入数据:pd.read_csv("文件名"),默认以逗号为分隔符 D:\data\ex1.csv文件内容: ...
- 创建自托管的SignalR服务端
微软官方例子地址:http://www.asp.net/signalr/overview/deployment/tutorial-signalr-self-host 1.说明: SignalR服务端可 ...