教学之友,学习之友。

站长教学网

当前位置: 站长教学网 > 数据库 > MYSQL教程 >

使用子查询提高MySQL分页效率

时间:2013-01-21 14:08来源:未知 作者:ken 点击:

这些天,陆续有几个人问过我其中的子查询方式,并对子查询分页的高效率表示质疑。今天我特意做了一个试验来验证这一点。

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

注意:如果想避免缓存的影响,可以使用SQL_NO_CACHE的方式:SELECT SQL_NO_CACHE ...

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

在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 秒

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

其实效率的差别就在于以下两种方式的差别:站长教学网 eduyo.com

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的优化器比较笨吧。

BTW:顺便要说一个事儿,就是搜索引擎的问题,在分页的时候,有时候要考虑搜索引擎的影响,比如你的数据一共有一万页,如果你不做限制的话,搜索引擎的爬虫会傻乎乎的一直检索下去,有时候检索到大分页的时候,就可能会给服务器负载造成负担,我们在尽可能提供分页效率的同时,也应该考虑一些其他的方式来限制爬虫的行为,比如说,我们可以限制一百页以后的分页必须是登陆状态下的用户才能访问,如此既没有严重影响用户体验,也屏蔽了爬虫造成的不必要的负载。
 

(责任编辑:ken)
TAG标签: mysql 子查询
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
注册登录:不允许匿名留言,登录后留言无需输入验证码。
栏目列表
最新内容