设为首页 加入收藏

TOP

mysql分页存储过程
2015-11-21 01:36:19 来源: 作者: 【 】 浏览:0
Tags:mysql 存储 过程

网上关于mysql分页存储过程的资料很多,但内容大同小异。作为初学者,引用mysql存储过程如下:

?

DELIMITER $$

USE `database1`$$ -- 数据库名称

DROP PROCEDURE IF EXISTS `Query_Pagination`$$? -- 分页存储过程名称,存在则删除

CREATE DEFINER=`root`@`%` PROCEDURE `Query_Pagination`(? -- 创建新的分页存储过程 ? IN _fields VARCHAR (2000), -- 显示的字段 ? IN _tables TEXT, -- 表名 ? IN _where VARCHAR (2000), --? where条件,可为空 ? IN _orderby VARCHAR (200), -- 排序条件,可为空 ? IN _pageindex INT, -- 开始页 ? IN _pagesize INT, -- 每页大小 ? OUT _totalcount INT, -- 总共行数 ? OUT _pagecount INT --? 总共页数 ) BEGIN ? SET @startrow = _pagesize * (_pageindex - 1) ; ? SET @pagesize = _pagesize ; ? SET @rowindex = 0 ; ? SET @strsql = CONCAT( ??? ' select sql_calc_found_rows @rowindex:=@rowindex+1 as rownumber,', -- 显示每条的行号 ??? _fields, ??? ' from ', ??? _tables, ??? CASE ????? IFNULL(_where, '') ????? WHEN '' ????? THEN '' ????? ELSE CONCAT(' where ', _where) ??? END, ????? CASE ????? IFNULL(_orderby, '') ????? WHEN '' ????? THEN '' ????? ELSE CONCAT(' order by ', _orderby) ??? END,? ??? ' limit ', ??? @startRow, ??? ',', ??? @pageSize ? ) ; ? PREPARE strsql FROM @strsql ; ? EXECUTE strsql ; ? SET _totalcount = FOUND_ROWS() ; ? IF (_totalcount <= _pagesize) ? THEN SET _pagecount = 1 ; ? ELSE IF (_totalcount % _pagesize > 0) ? THEN SET _pagecount = _totalcount / _pageSize + 1 ; ? ELSE SET _pagecount = _totalcount / _pageSize ; ? END IF ; ? END IF ; END$$

DELIMITER ;

?

上述分页存储过程的确很好用,但是当数据量达到百万级时,发现速度就会下降,用explain执行以下语句:

EXPLAIN SELECT SQL_CALC_FOUND_ROWS @rowindex:=@rowindex+1 AS rownumber FROM view_visitregisterinfo WHERE CardType='1' ORDER BY tableid DESC LIMIT 0,1000;

执行结果如下:

\
可以看到,虽然用了limit 但是依然检索了整个表,导致查询缓慢。执行时间为16秒。

去掉SQL_CALC_FOUND_ROWS @rowindex:=@rowindex+1 AS rownumber ,查询语句改为EXPLAIN SELECT * FROM view_visitregisterinfo WHERE 1=1 AND CardType='1' ORDER BY tableid DESC LIMIT 0,1000; 执行结果如下:\

可以看到,执行的行数为1000,执行时间为0.038s,时间加快了很多。

所以,修改存储过程为:

DELIMITER $$

USE `speednew`$$ -- 数据库名称

DROP PROCEDURE IF EXISTS `Query_Pagination`$$  -- 分页存储过程名称,存在则删除

CREATE DEFINER=`root`@`%` PROCEDURE `Query_Pagination`(  -- 创建新的分页存储过程
  IN _fields VARCHAR (2000), -- 显示的字段
  IN _tables TEXT, -- 表名
  IN _where VARCHAR (2000), --  where条件,可为空
  IN _orderby VARCHAR (200), -- 排序条件,可为空
  IN _pageindex INT, -- 开始页
  IN _pagesize INT, -- 每页大小
  OUT _totalcount INT, -- 总共行数
  OUT _pagecount INT --  总共页数
)
BEGIN
  SET @startrow = _pagesize * (_pageindex - 1) ;
  SET @pagesize = _pagesize ;
  SET @rowindex = 0 ;
  SET @strsql = CONCAT(
    ' select ', 
    _fields,
    ' from ',
    _tables,
    CASE
      IFNULL(_where, '') 
      WHEN '' 
      THEN '' 
      ELSE CONCAT(' where ', _where) 
    END,
      CASE
      IFNULL(_orderby, '') 
      WHEN '' 
      THEN '' 
      ELSE CONCAT(' order by ', _orderby) 
    END,  
    ' limit ',
    @startRow,
    ',',
    @pageSize
  ) ;
  PREPARE strsql FROM @strsql ;
  EXECUTE strsql ;
  SET _totalcount = FOUND_ROWS() ;
  IF (_totalcount <= _pagesize) 
  THEN SET _pagecount = 1 ;
  ELSE IF (_totalcount % _pagesize > 0) 
  THEN SET _pagecount = _totalcount / _pageSize + 1 ;
  ELSE SET _pagecount = _totalcount / _pageSize ;
  END IF ;
  END IF ;
END$$

DELIMITER ;


总结经验:引用现有的东西时,一定要根据个人的情况进行二次修改,改为适合自己的,同时要明白别人原先那样写的原因。

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇dba_dependencies视图的查询结果 下一篇MySQL创建表时,设置时间字段自动..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: