分页

 MySQL中的分页相对SQL Server来说就简单多了,因为它有现成的语句limit用来分页,它可以接收一个或者两个参数:

  • 接收两个参数时

SELECT * FROM City LIMIT 5,10;

  第一个参数是相对于结果集中第一行的偏移量,这个偏移量是从0开始的,也就是说第一行的偏移量是0,而不是1,

  第二个参数指的是返回结果的最大行数,即如果不够该数目,则返回实际的数量。

接收一个参数时

  指定返回的行数,相对于第一行,比如:

    SELECT * FROM world.city LIMIT 10;
  效果等于:

    SELECT * FROM world.city LIMIT 0,10;
  在使用的过程中注意:

  limit后面只能使用非负、整型的常数:也就是说后面只能是1,100等整型数字,而一些表达式也是不允许的,比如100+200等等;

  在子查询中,外部的查询中使用的limit的优先级要高于子查询中limit,比如:

    (SELECT * FROM world.city LIMIT 3) LIMIT 5;
  最后返回5行。


  由于limit后面只能使用非负、整型常数,因此无法使用变量,如下分页语句会错误:

set @pageSize = 10; 
set @pageIndex = 2;
select * from city LIMIT (@pageIndex-1)*@pageSize, @pageSize;

  但是limit在预编译语句中可以使用?作为占位符来传递参数,但是在使用预编译语句的时候如下的语句都是错误的:

  • 传递参数变量表达式:
set @pageSize = 10; 
set @pageIndex = 2;

PREPARE stmt FROM 'select * from city LIMIT ?, ?';
EXECUTE stmt USING (@pageIndex-1)*@pageSize, @pageSize;
  • 在limit后面使用表达式:
set @pageSize = 10; 
set @pageIndex = 2;

PREPARE stmt FROM 'select * from city LIMIT (?-1)*?, ?';
EXECUTE stmt USING @pageIndex, @pageSize, @pageSize;

正确的预编译分页方法如下:

set @pageSize = 10; 
set @pageIndex = 2;
set @off = (@pageIndex-1)*@pageSize;

PREPARE stmt FROM 'select * from city LIMIT ?, ?';
EXECUTE stmt USING @off, @pageSize;

另外也可以使用存储过程来完成分页的查询,如下:

DROP PROCEDURE IF EXISTS Page_Query;
CREATE PROCEDURE Page_Query(pageIndex int, pageSize int)
BEGIN
    DECLARE off int;
    SET off = (pageIndex-1)*pageSize;
    SELECT * FROM world.city LIMIT off, pageSize; 
END

CALL Page_Query(2, 10);

在分页的过程中,如果遇到的数据量很大还会遇到性能问题,尤其是如下语句:

SELECT * FROM world.city LIMIT 100000, 20;

如果每次我们把上次查询的偏移量记下在进行查询则会快很多:

SELECT * FROM world.city where Id > 100000 LIMIT 20;

 

参考

     原文:https://blog.csdn.net/lmy86263/article/details/61469958 

posted on 2018-10-26 19:47  溪水静幽  阅读(239)  评论(0)    收藏  举报