一.直接使用limit最简单查询方法:

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

在中小数据量的情况下,这样的SQL足够用了,唯一需要注意的问题就是确保使用了索引。

随着数据量的增加,页数会越来越多,查看后几页的SQL就可能类似:

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

言以蔽之,就是越往后分页,LIMIT语句的偏移量就会越大,速度也会明显变慢。

此时,通过2中方式:

二.子查询分页方式来提高效率

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

  1. SELECT * FROM `log_data` WHERE id <=
  2. (SELECT id FROM `log_data` ORDER BY id desc LIMIT 5, 1) ORDER BY id desc LIMIT 5

为什么会这样呢?因为子查询是在索引上完成的,而普通的查询时在数据文件上完成的,通常来说,索引文件要比数据文件小得多,所以操作起来也会更有效率。

(via)通过explain SQL语句发现:子查询使用了索引

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

三.JOIN分页方式

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

  1. SELECT * FROM `log_data` AS t1
  2. JOIN (SELECT id FROM `log_data` ORDER BY id desc LIMIT 5, 1) AS t2
  3. WHERE t1.id <= t2.id ORDER BY t1.id desc LIMIT 5;

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

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

四.使用mysql的found_rows()函数查询

Mysql FOUND_ROWS() 函数结合SQL_CALC_FOUND_ROWS在SELECT中可以得到两个结果:

  1. 1. 得到Limit的内容
  2. 2. 得到去除Limit以后所有行数

SELECT语句中经常可能用LIMIT限制返回行数。有时候可能想要知道如果没有LIMIT会返回多少行,但又不想再执行一次相同语句。那么,在SELECT查询中包含SQL_CALC_FOUND_ROWS选项,然后执行FOUND_ROWS()就可以了:

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

其中SQL_CALC_FOUND_ROWS 告诉Mysql将sql所处理的行数记录下来,FOUND_ROWS() 则取到了这个纪录。 虽然也是两个语句,但是只执行了一次主查询,所以效率比原来要高很多。

  1. 1. 如果在前一条语句中使用SQL_CALC_FOUND_ROWS选项,FOUND_ROWS()将返回第一条语句没有LIMIT时返回的行数。
  2. 2. 如果在前一条语句中没有使用SQL_CALC_FOUND_ROWS选项,FOUND_ROWS()将返回前一条语句实际返回的行数。

如果使用 SELECT SQL_CALC_FOUND_ROWS,MySQL必须计算所有结果集的行数。尽管这样,总比再执行一次不使用LIMIT的查询要快多了吧,因为那样结果集要返回客户端滴。(另外:应该不单是没有将结果集返回的原因,还有原因可能是比如LIKE之类比较费劲的SQL不需要再去劳累一次。)

  1. -- 注意下面语句中的条件 LIKE
  2. SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name WHERE Name LIKE '%string%' id > 100 LIMIT 10;
  3. SELECT FOUND_ROWS();
  1. -- 上面语句等价于下面语句,但性能方面应该提升非常非常的明显:
  2. SELECT COUNT(*) FROM tbl_name WHERE Name LIKE '%string%' ;
  3. SELECT * FROM tbl_name WHERE Name LIKE '%string%' id > 100 LIMIT 10;

五.使用存储过程

  1. DELIMITER $$;
  2. DROP PROCEDURE IF EXISTS `sp_page`$$
  3. CREATE PROCEDURE `sp_page`(
  4. in _pagecurrent int,/*当前页*/
  5. in _pagesize int,/*每页的记录数*/
  6. in _ifelse varchar(1000),/*显示字段*/
  7. in _where varchar(1000),/*条件*/
  8. in _order varchar(1000)/*排序*/
  9. )
  10. COMMENT '分页存储过程'
  11. BEGIN
  12. if _pagesize<=1 then
  13. set _pagesize=20;
  14. end if;
  15. if _pagecurrent < 1 then
  16. set _pagecurrent = 1;
  17. end if;
  18.  
  19. set @strsql = concat('select ',_ifelse,' from ',_where,' ',_order,' limit ',_pagecurrent*_pagesize-_pagesize,',',_pagesize);
  20. prepare stmtsql from @strsql;
  21. execute stmtsql;
  22. deallocate prepare stmtsql;
  23. set @strsqlcount=concat('select count(1) as count from ',_where);/*count(1) 这个字段最好是主键*/
  24. prepare stmtsqlcount from @strsqlcount;
  25. execute stmtsqlcount;
  26. deallocate prepare stmtsqlcount;
  27. END$$
  28. DELIMITER ;$$

调用代码

  1. 调用例1 call sp_Page(1,3,'*','test','order by id desc');
  2.  
  3. 调用例2 call sp_Page(1,3,'*','test where sort=1','order by id desc');
  4.  
  5. 调用例3 call sp_Page(1,3,'id,title','test where sort=1','order by id desc');

mysql-分页查询方案的更多相关文章

  1. 复盘MySQL分页查询优化方案

    一.前言 MySQL分页查询作为Java面试的一道高频面试题,这里有必要实践一下,毕竟实践出真知. 很多同学在做测试时苦于没有海量数据,官方其实是有一套测试库的. 二.模拟数据 这里模拟数据分2种情况 ...

  2. 使用聚集索引和非聚集索引对MySQL分页查询的优化

    内容摘录来源:MSSQL123 ,lujun9972.github.io/blog/2018/03/13/如何编写bash-completion-script/ 一.先公布下结论: 1.如果分页排序字 ...

  3. mysql 分页查询

    mysql,; : mysql,; -last. //如果只给定一个参数,它表示返回最大的记录行数目: mysql; 个记录行 ,n. 动态传参的分页查询 SELECT * FROM table LI ...

  4. mysql分页查询详解

    我们做的后端项目一般都会有admin管理端,当管理端将要展示数据的时候,就需要用到分页.所以分页的考查在面试中也相当多.在mysql中进行分页查询时,一般会使用limit查询,而且通常查询中都会使用o ...

  5. Java GUI+mysql+分页查询

    1.要求 : 创建一个学生信息管理数据库 2.实现分页查询 代码如下: a)学生实体类: /** * @author: Annie * @date:2016年6月23日 * @description: ...

  6. Mysql分页查询性能分析

    [PS:原文手打,转载说明出处,博客园] 前言 看过一堆的百度,最终还是自己做了一次实验,本文基于Mysql5.7.17版本,Mysql引擎为InnoDB,编码为utf8,排序规则为utf8_gene ...

  7. MySql分页查询慢|这里告诉你答案

    一.背景 我们在开发的过程中使用分页是不可避免的,通常情况下我们的做法是使用limit加偏移量:select * from table where column=xxx order by xxx li ...

  8. MySQL分页查询性能优化

    当需要从数据库查询的表有上万条记录的时候,一次性查询所有结果会变得很慢,特别是随着数据量的增加特别明显,这时需要使用分页查询.对于数据库分页查询,也有很多种方法和优化的点.下面简单说一下我知道的一些方 ...

  9. MySQL分页查询大数据量优化方法

    方法1: 直接使用数据库提供的SQL语句 语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N适应场景: 适用于数据量较少的情况(元组百/千级)原因/缺点: ...

  10. mysql分页查询语法

    一.limit语法 SELECT * FROM table LIMIT [offset,] rows | rows OFFSET offset LIMIT 子句可以被用于强制 SELECT 语句返回指 ...

随机推荐

  1. Linq中查询List组合相同值数量大于1

     List< select g.Key).ToList();

  2. ios开发中如何隐藏各种bar

    转载自http://www.cnblogs.com/lovecode/articles/2234557.html 状态条Status Bar [UIApplication sharedApplicat ...

  3. ruby on rails 里使用SideKiq 做后台任务

    环境:ubuntu14.4,ruby2.1.5, rails4.2 一.新一个rais项目:rails new active_job --skip-bundle       进入项目文件夹: cd a ...

  4. [转]PHP 获取服务器详细信息代码

    转自:http://jingyan.baidu.com/article/fdbd4277049c8bb89e3f4893.html 获取系统类型及版本号: php_uname() (例:Windows ...

  5. C++的CreateThread实例

    function CreateThread(  lpThreadAttributes: Pointer;           {安全设置}  dwStackSize: DWORD;           ...

  6. php基础24:数组range

    <?php $numbers = range(1, 10); echo "<pre>"; var_dump($numbers); echo "</ ...

  7. CSS 实现加载动画之二-圆环旋转

    上次简单的介绍了下如何用代码实现菊花旋转的加载动画,动画点击,这次继续我们的动画系列,实现另外一种加载动画,圆环旋转.与上次不同的是,菊花旋转是通过改变元素透明度来实现动画,这次因为考虑到元素叠加,加 ...

  8. ant命令总结

    ant命令总结 博客分类: 版本管理 svn , maven , ant   ant命令总结 1 Ant是什么?  Apache Ant 是一个基于 Java的生成工具. 生成工具在软件开发中用来将源 ...

  9. [CareerCup] 11.1 Merge Arrays 合并数组

    11.1 You are given two sorted arrays, A and B, where A has a large enough buffer at the end to hold ...

  10. Chrome扩展开发(Gmail附件管理助手)系列之〇——概述

    目录: 0.Chrome扩展开发(Gmail附件管理助手)系列之〇——概述 1.Chrome扩展开发之一——Chrome扩展的文件结构 2.Chrome扩展开发之二——Chrome扩展中脚本的运行机制 ...