MySQL分页的同时查询记录总数 SQL_CALC_FOUND_ROWS的性能测试
来源:互联网 发布:unity3d obj 文件导入 编辑:程序博客网 时间:2024/06/04 18:42
select * from auth_user
SELECT FOUND_ROWS() //返回查询记录的总数
select sql_calc_found_rows col_name from table_name limit 5,3;
select found_rows()
SELECT语句中加上修饰SQL_CALC_FOUND_ROWS
加上SQL_CALC_FOUND_ROWS之后,即使你用了limit n,m ,SELECT FOUND_ROWS() 仍会返回满足条件记录的总数。这样,你执行完 select 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/- MySQL分页的同时查询记录总数 SQL_CALC_FOUND_ROWS的性能测试
- 使用SQL_CALC_FOUND_ROWS获取mysql查询记录总数
- 使用limit查询的同时取得总的记录数:SQL_CALC_FOUND_ROWS和FOUND_ROWS()
- 使用limit查询的同时取得总的记录数:SQL_CALC_FOUND_ROWS和FOUND_ROWS()
- 取得查询的记录总数分页显示用的方法
- MySQL 分页查询: To SQL_CALC_FOUND_ROWS or not to SQL_CALC_FOUND_ROWS?
- mysql 同时返回查询总数及分页数据
- mysql的SQL_CALC_FOUND_ROWS 使用
- mysql的SQL_CALC_FOUND_ROWS 使用
- mysql的SQL_CALC_FOUND_ROWS 使用
- mysql的SQL_CALC_FOUND_ROWS 使用
- mysql的SQL_CALC_FOUND_ROWS 使用
- mysql的SQL_CALC_FOUND_ROWS 使用
- mysql的SQL_CALC_FOUND_ROWS 使用
- mysql SQL_CALC_FOUND_ROWS的用途
- MySql中,查询不重复记录的总数的方法
- Mysql查询记录总数
- mysql查询不重复的记录总数distinct用法
- WEBAPP介绍及其iOS Web开发技巧总结
- IOS 开发常用的宏定义
- Java 正则表达式
- linux库链接问题-找不到库
- 留言本之可以分行读取留言内容
- MySQL分页的同时查询记录总数 SQL_CALC_FOUND_ROWS的性能测试
- 正则表达式 匹配中文,英文字母和数字及_长度详解
- 在MarkDown中插入本地图片
- hibernate jpa 注解 @Temporal(TemporalType.DATE) 格式化时间日期,页面直接得到格式化类型的值
- 必须知道的八大种排序算法【java实现】(一) 冒泡排序、快速排序
- 如何在编译时改变App的图标
- cent python3离线安装setuptools
- cvc-complex-type.2.4.a: Invalid content was found
- shell-find使用