百度首页 | 百度空间
 
查看文章
 
验证使用子查询提高MySQL分页效率
2008年05月12日 星期一 下午 04:51
作者:老王

很久以前,我写过一篇文章,说明了MySQL下的几种分页方式。这些天,陆续有几个人问过我其中的子查询方式,并对子查询分页的高效率表示质疑。今天我特意做了一个试验来验证这一点。

我选择了公司一个Discuz测试论坛作为试验体,其cdb_posts的记录数接近10000000行。

先验证最基本的分页方式:

在PhpMyAdmin里执行如下SQL:

SELECT * FROM `cdb_posts` ORDER BY pid LIMIT 1000000 , 30

多执行几次,避免Cache等影响,取平均值,其执行时间大约为:6.6140 秒

再验证子查询的分页方式:

在PhpMyAdmin里执行如下SQL:

SELECT * FROM `cdb_posts` WHERE pid >= (
    SELECT pid FROM `cdb_posts` ORDER BY pid LIMIT 1000000 , 1
) LIMIT 30

同样多执行几次,避免Cache等影响,取平均值,其执行时间大约为:0.6049 秒

=================

其实效率的差别就在于以下两种方式的差别:

SELECT * FROM `cdb_posts` ORDER BY pid LIMIT 1000000 , 1(6.7732 秒
SELECT pid FROM `cdb_posts` ORDER BY pid LIMIT 1000000 , 1
0.5838 秒

有网友说如果是MySQL静态表的话,两个查询的速度应该基本一样,到底是不是我再做实验验证一下,同样是上面所用的表,只是删除了所有的varchar, text之类的变长度字段,以保证其是静态表,然后执行:

SELECT * FROM `cdb_posts` ORDER BY pid LIMIT 1000000 , 1(2.1303 秒
SELECT pid FROM `cdb_posts` ORDER BY pid LIMIT 1000000 , 1
0.5532 秒

可以发现,转换成静态表之后,SELECT *后的速度确实快了一些,但查询速度仍然处于秒的级别,可以说还是很慢的。

综上所述:当限定了字段,并且这个字段是一个索引的时候,LIMIT可以直接在索引文件中查找,而不是在实际的数据文件中查找,所以需要“跨越”的数据块体积要小很多。不过感觉这本应该可以在MySQL内部得到透明的优化才对,或许是因为MySQL的优化器比较笨吧。

类别:Mysql | 添加到搜藏 | 浏览() | 评论 (5)
 
最近读者:
 
网友评论:
1
2008年05月12日 星期一 下午 05:42
呵呵,以前这样弄过,不过这样出来的分页结果不是很正确,就是因为条件>=
其实速度的提升不在于子查询,而在于这个条件。
 
3
2008年05月12日 星期一 下午 08:38
后者走的是索引,当然比前者快。
 
4
2008年05月13日 星期二 上午 04:33
晕倒,一个使用了索引,一个没有
这也可以比较?
 
7
2008年06月06日 星期五 下午 04:46
不明白了,难道第一个sql里的pid不是走的索引吗?
 
8
2008年07月10日 星期四 下午 10:44
我同意xjtdy888 的意见. 实际上子查询解决的是 外面查询的条件定位.
如果更合理的在子查询里用MAX 或者MIN 计算 是不是会更快呢.
 
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码:
 

     

©2008 Baidu