MySQL高效分页解决方案集分享

 更新时间:2013年11月01日 15:38:09   作者:  
这篇文章介绍了MySQL高效分页解决方案集,有需要的朋友可以参考一下
一,最常见MYSQL最基本的分页方式:
复制代码 代码如下:

select * from content order by id desc limit 0, 10

在中小数据量的情况下,这样的SQL足够用了,唯一需要注意的问题就是确保使用了索引。随着数据量的增加,页数会越来越多,查看后几页的SQL就可能类似:
复制代码 代码如下:

select * from content order by id desc limit 10000, 10

一言以蔽之,就是越往后分页,LIMIT语句的偏移量就会越大,速度也会明显变慢。
此时,我们可以通过2种方式:
一,子查询的分页方式来提高分页效率,飘易用的SQL语句如下:
复制代码 代码如下:

SELECT * FROM `content` WHERE id (SELECT id FROM `content` ORDER BY id desc LIMIT ".($page-1)*$pagesize.", 1) ORDER BY id desc LIMIT $pagesize

为什么会这样呢?因为子查询是在索引上完成的,而普通的查询时在数据文件上完成的,通常来说,索引文件要比数据文件小得多,所以操作起来也会更有效率。(via)通过explain SQL语句发现:子查询使用了索引!
复制代码 代码如下:

id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY content range PRIMARY PRIMARY 4 NULL 6264 Using where
2 SUBQUERY content index NULL PRIMARY 4 NULL 27085 Using index

经过飘易的实测,使用子查询的分页方式的效率比纯LIMIT提高了14-20倍!
二,JOIN分页方式
复制代码 代码如下:

select * FROM `content` AS t1
JOIN (SELECT id FROM `content` ORDER BY id desc LIMIT ".($page-1)*$pagesize.", 1) AS t2
WHERE t1.id

经过我的测试,join分页和子查询分页的效率基本在一个等级上,消耗的时间也基本一致。explain SQL语句:
复制代码 代码如下:

id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY system NULL NULL NULL NULL 1
1 PRIMARY t1 range PRIMARY PRIMARY 4 NULL 6264 Using where
2 DERIVED content index NULL PRIMARY 4 NULL 27085 Using index

三,使用MYSQL的FOUND_ROWS()函数
Mysql FOUND_ROWS() 函数结合SQL_CALC_FOUND_ROWS在SELECT中可以得到两个结果:
1. 得到Limit的内容
2. 得到去除Limit以后所有行数
SELECT语句中经常可能用LIMIT限制返回行数。有时候可能想要知道如果没有LIMIT会返回多少行,但又不想再执行一次相同语句。那么,在SELECT查询中包含SQL_CALC_FOUND_ROWS选项,然后执行FOUND_ROWS()就可以了:
复制代码 代码如下:

select SQL_CALC_FOUND_ROWS * FROM tbl_name WHERE id > 100 LIMIT 10;
SELECT FOUND_ROWS();

其中SQL_CALC_FOUND_ROWS 告诉Mysql将sql所处理的行数记录下来,FOUND_ROWS() 则取到了这个纪录。 虽然也是两个语句,但是只执行了一次主查询,所以效率比原来要高很多。
1. 如果在前一条语句中使用SQL_CALC_FOUND_ROWS选项,FOUND_ROWS()将返回第一条语句没有LIMIT时返回的行数。
2. 如果在前一条语句中没有使用SQL_CALC_FOUND_ROWS选项,FOUND_ROWS()将返回前一条语句实际返回的行数。
如果使用 SELECT SQL_CALC_FOUND_ROWS,MySQL必须计算所有结果集的行数。尽管这样,总比再执行一次不使用LIMIT的查询要快多了吧,因为那样结果集要返回客户端滴。(另外:应该不单是没有将结果集返回的原因,还有原因可能是比如LIKE之类比较费劲的SQL不需要再去劳累一次。)
复制代码 代码如下:

-- 注意下面语句中的条件 LIKE
SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name WHERE Name LIKE '%string%' id > 100 LIMIT 10;
SELECT FOUND_ROWS();

复制代码 代码如下:

-- 上面语句等价于下面语句,但性能方面应该提升非常非常的明显:
SELECT COUNT(*) FROM tbl_name WHERE Name LIKE '%string%' ;
SELECT * FROM tbl_name WHERE Name LIKE '%string%' id > 100 LIMIT 10;

相关文章

  • MySQL基本增删改查语句练习(最新推荐)

    MySQL基本增删改查语句练习(最新推荐)

    这篇文章主要介绍了MySQL基本增删改查语句练习,本文给大家分享sql增删改查语句是平时开发最常用的,需要的朋友可以参考下
    2023-01-01
  • MySQL递归查找树形结构(这个方法太实用了!)

    MySQL递归查找树形结构(这个方法太实用了!)

    对于数据库中的树形结构数据,如部门表,有时候,我们需要知道某部门的所有下属部分或者某部分的所有上级部门,这时候就需要用到mysql的递归查询,下面这篇文章主要给大家介绍了关于MySQL递归查找树形结构的相关资料,需要的朋友可以参考下
    2022-11-11
  • mysql 5.7 的 /etc/my.cnf 参数介绍

    mysql 5.7 的 /etc/my.cnf 参数介绍

    这篇文章主要介绍了mysql 5.7 的 /etc/my.cnf 参数介绍,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • MySQL打开时在命令行输入密码后,按回车键闪退的解决方案

    MySQL打开时在命令行输入密码后,按回车键闪退的解决方案

    当MySQL在命令行中输入密码后闪退,无法显示欢迎信息时,可尝试通过计算机管理以管理员身份运行服务,启动MySQL服务,确保MySQL服务已经启动,再次进入命令行界面,应能看到欢迎信息,表明MySQL启动成功,这一方法简单易行,适用于遇到相同问题的用户
    2024-10-10
  • mysql 如何动态修改复制过滤器

    mysql 如何动态修改复制过滤器

    这篇文章主要介绍了mysql 如何动态修改复制过滤器,帮助大家更好的理解和使用MySQL,感兴趣的朋友可以了解下
    2020-11-11
  • 数据库索引的知识点整理小结,你所需要了解的都在这儿了

    数据库索引的知识点整理小结,你所需要了解的都在这儿了

    这篇文章主要介绍了数据库索引的知识点整理小结,你所需要了解的都在这儿了,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • mysql全量备份和快速恢复的方法整理

    mysql全量备份和快速恢复的方法整理

    在本篇文章里小编给各位整理的是关于mysql全量备份和快速恢复的方法整理内容,需要的朋友们可以参考下。
    2020-03-03
  • Ubuntu下mysql与mysql workbench安装教程

    Ubuntu下mysql与mysql workbench安装教程

    这篇文章主要为大家详细介绍了Ubuntu下mysql与mysql workbench的安装教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-04-04
  • MySQL版oracle下scott用户建表语句实例

    MySQL版oracle下scott用户建表语句实例

    这篇文章主要给大家介绍了关于MySQL版oracle下scott用户建表语句的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-02-02
  • IOS 数据库升级数据迁移的实例详解

    IOS 数据库升级数据迁移的实例详解

    这篇文章主要介绍了IOS 数据库升级数据迁移的实例详解的相关资料,这里提供实例帮助大家解决数据库升级及数据迁移的问题,需要的朋友可以参考下
    2017-07-07

最新评论