MySQL数据库中,自定义存储过程查询表中的数据,带有分页功能。具体实例如下代码:

 1 DROP PROCEDURE IF EXISTS `sampledb`.`proc_GetPagedDataSet`;

 CREATE DEFINER=`root`@`%` PROCEDURE `proc_GetPagedDataSet`(
IN tableName VARCHAR (20), /*表名
IN pageIndex INT, /*当前页*/
IN pageSize INT, /*每页记录数*/
OUT pageCount INT,/*总记录分页数*/
out totalRecordCount int /*总记录数*/)
BEGIN
/*获取表中的记录数*/
set @recordCount=0;
set @sql='';
set @sql=CONCAT('select count(*) into @recordCount from ',tableName);
prepare stmt from @sql; /*预处理 自定义sql字符串*/
execute stmt; /*执行自定义sql语句*/
deallocate prepare stmt; /*释放预处理资源*/ set totalRecordCount = @recordCount; /*总记录数*/ /*计算返回多少页*/
set @tmp=1;
set @tmp=@recordCount mod pageSize; /*取余数*/
if @tmp=0 then
set pageCount=@recordCount div pageSize;
else
set pageCount=@recordCount div pageSize + 1;
end if; /*分页显示数据*/
set @sql=CONCAT('select * from ',tableName,' limit ',(pageIndex-1)*pageSize,',',pageSize);
prepare stmt from @sql; /*预处理 自定义sql字符串*/
execute stmt;/*执行自定义sql语句*/
deallocate prepare stmt; /*释放预处理资源*/
END =============================================================================================== MySQL大数据量分页性能优化

mysql大数据量使用limit分页,随着页码的增大,查询效率越低下。
测试实验
1. 直接用limit start, count分页语句, 也是我程序中用的方法:

select * from product limit start, count
当起始页较小时,查询没有性能问题,我们分别看下从10, 100, 1000, 10000开始分页的执行时间(每页取20条), 如下:

select * from product limit 10, 20 0.016秒
select * from product limit 100, 20 0.016秒
select * from product limit 1000, 20 0.047秒
select * from product limit 10000, 20 0.094秒

我们已经看出随着起始记录的增加,时间也随着增大, 这说明分页语句limit跟起始页码是有很大关系的,那么我们把起始记录改为40w看下(也就是记录的一般左右) select * from product limit 400000, 20 3.229秒

再看我们取最后一页记录的时间
select * from product limit 866613, 20 37.44秒

难怪搜索引擎抓取我们页面的时候经常会报超时,像这种分页最大的页码页显然这种时
间是无法忍受的。

从中我们也能总结出两件事情:
1)limit语句的查询时间与起始记录的位置成正比
2)mysql的limit语句是很方便,但是对记录很多的表并不适合直接使用。

2. 对limit分页问题的性能优化方法

利用表的覆盖索引来加速分页查询
我们都知道,利用了索引查询的语句中如果只包含了那个索引列(覆盖索引),那么这种情况会查询很快。

因为利用索引查找有优化算法,且数据就在查询索引上面,不用再去找相关的数据地址了,这样节省了很多时间。另外Mysql中也有相关的索引缓存,在并发高的时候利用缓存就效果更好了。

在我们的例子中,我们知道id字段是主键,自然就包含了默认的主键索引。现在让我们看看利用覆盖索引的查询效果如何:

这次我们之间查询最后一页的数据(利用覆盖索引,只包含id列),如下:
select id from product limit 866613, 20 0.2秒
相对于查询了所有列的37.44秒,提升了大概100多倍的速度

那么如果我们也要查询所有列,有两种方法,一种是id>=的形式,另一种就是利用join,看下实际情况:

SELECT * FROM product WHERE ID > =(select id from product limit 866613, 1) limit 20
查询时间为0.2秒,简直是一个质的飞跃啊,哈哈

另一种写法
SELECT * FROM product a JOIN (select id from product limit 866613, 20) b ON a.ID = b.id
查询时间也很短,赞!

其实两者用的都是一个原理嘛,所以效果也差不多

 
 

MySQL 存储过程中分页的更多相关文章

  1. MYSQL存储过程中常使用的命令记录

    MYSQL存储过程中常使用的命令记录 1.触发器trigger 查看:show triggers; 2.存储过程procedure 查看:show procedure status; 查看详细:sho ...

  2. MYSQL存储过程中的IN、OUT和INOUT

    MYSQL存储过程中的IN.OUT和INOUT,不能简单理解为一个方法的参数和返回值,而是面向整个过程上下文变量的. 一.MySQL 存储过程参数(in) 基本可以理解为传入function的参数,而 ...

  3. Mysql 存储过程中使用多游标

    Mysql 存储过程中使用多游标 drop procedure IF EXISTS test_proc_1; create procedure test_proc_1() begin ; ) ; ) ...

  4. MySQL存储过程中使用SELECT …INTO语句为变量赋值

    使用SELECT …INTO语句为变量赋值 在MySQL存储过程中,可以使用SELECT …INTO语句对变量进行赋值,该语句在数据库中进行查询,并将得到的结果赋值给变量.SELECT …INTO语句 ...

  5. 【转】MySQL存储过程中使用动态行转列

    MySQL存储过程中使用动态行转列 最近做项目关于数据报表处理,然而数据库存储格式和报表展现形式不同,需要进行一下行转列的操作,在做上一个项目的时候也看了一下,但是后来换了读取方式,也就没深入研究这个 ...

  6. mysql -- 存储过程中 declare 和 set 定义变量的区别

    mysql存储过程中,定义变量有两种方式:1.使用set或select直接赋值,变量名以 @ 开头.例如:set @var=1;可以在一个会话的任何地方声明,作用域是整个会话,称为会话变量. 2.以 ...

  7. MySQL存储过程中的3种循环,存储过程的基本语法,ORACLE与MYSQL的存储过程/函数的使用区别,退出存储过程方法

    在MySQL存储过程的语句中有三个标准的循环方式:WHILE循环,LOOP循环以及REPEAT循环.还有一种非标准的循环方式:GOTO,不过这种循环方式最好别用,很容易引起程序的混乱,在这里就不错具体 ...

  8. mysql存储过程中 乱码问题解决办法

    中文乱码无论在何时都是一个头疼的问题,mysql的存储过程参数也同样存在这个问题.1.直接使用insert into语句没问题,能够正常插入汉字.2.把insert into语句移到Procedure ...

  9. mysql 存储过程中limit

    1.mysql的高版本(5.5),存储过程中的limit可以使用变量,如下:select * from student limit iStart,iNum; 2.mysql的低版本(5.1),存储过程 ...

随机推荐

  1. Spring HibernateTemplate与HibernateDaoSupport对比

    HibernateTemplate与HibernateDaoSupport两者都是spring整合hibernate提供的模板技术. 对于保存一个对象,HibernateTemplate需要先配置 配 ...

  2. Media Query-响应式布局

    做响应式网站的时候,一定要在页面头部加入如下的声明: <meta name="viewport" content="width=device-width, init ...

  3. PHP一维数组转二维数组正则表达式

    2017年11月20日17:17:08 array(1 => '哈哈')  变成  array('id' => 1, 'name' => '哈哈') 查找目标:  (\d)\s=&g ...

  4. FTP登录提示Can't open data connection for transfer of "/"

    服务器: 系统:windows server 2008 R2 standard 是否开启防火墙:是 FTP客户端:Filezilla server 本地: FTP服务端:winscp 使用winscp ...

  5. 51nod--1240莫比乌斯函数 (数论)

    题目: 1240 莫比乌斯函数 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 莫比乌斯函数,由德国数学家和天文学家莫比乌斯提出.梅滕斯(Mertens)首先 ...

  6. Java二维码生成与解码

      基于google zxing 的Java二维码生成与解码   一.添加Maven依赖(解码时需要上传二维码图片,所以需要依赖文件上传包) <!-- google二维码工具 --> &l ...

  7. Webapi 跨域 解决解决错误No 'Access-Control-Allow-Origin' header is present on the requested resource 问题

    首先是web端(http://localhost:53784) 请求 api(http://localhost:81/api/)时出现错误信息: 查看控制台会发现错误:XMLHttpRequest c ...

  8. Go语言环境安装&搭建(Linux)

    Linux的东西果然不记不行啊~ 下载&安装 下载 我们先找到linux版的下载链接 https://golang.org/dl/ 打开网址找到Linux对应的链接右键复制下载地址 然后连接服 ...

  9. 分布式系统的一致性协议之 2PC 和 3PC

    在分布式系统领域,有一个理论,对于分布式系统的设计影响非常大,那就是 CAP 理论,即对于一个分布式系统而言,它是无法同时满足 Consistency(强一致性).Availability(可用性) ...

  10. 体验go语言的风骚式编程

    最近想搞搞后台开发,话说注意力就转移到了公司用的golang.用Go做微服务比较方便,或许是因为golang强悍的语法吧,看到go的语法,自己已被深深的吸引.关于学习后台如何选择可以参考<做后台 ...