分页
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
立志如山 静心求实
浙公网安备 33010602011771号