一、Limit-offset分页语法如下:
SELECT select_list
FROM table_expression
[ ORDER BY ... ]
[ LIMIT { number | ALL } ] [ OFFSET number ]
二、Limit-offset分页查询示例:
创建一个测试表:
postgres=#
CREATE TABLE student (
studentID CHAR(6) primary key,
sname VARCHAR(8),
sex CHAR(2) DEFAULT '男',
birthday TIMESTAMP
);
插入6条数据:
postgres=#
INSERT INTO student(studentID,sname,sex,birthday) VALUES('201001','张三','男','1990-05-11');
INSERT INTO student(studentID,sname) VALUES('201002','李四');
INSERT INTO student(studentID,sname,sex,birthday) VALUES('201003','王五','女','1991-10-15');
INSERT INTO student(studentID,sname,sex,birthday) VALUES('201004','王凯','男','1992-11-09');
INSERT INTO student(studentID,sname,sex,birthday) VALUES('201005','赵五','男','1990-05-25');
INSERT INTO student(studentID,sname,sex,birthday) VALUES('201006','孙六','女','1991-08-27');
student表的数据情况如下:
postgres=# select * from student;
studentid | sname | sex | birthday
-----------+-------+-----+---------------------
201001 | 张三 | 男 | 1990-05-11 00:00:00
201002 | 李四 | 男 |
201003 | 王五 | 女 | 1991-10-15 00:00:00
201004 | 王凯 | 男 | 1992-11-09 00:00:00
201005 | 赵五 | 男 | 1990-05-25 00:00:00
201006 | 孙六 | 女 | 1991-08-27 00:00:00
(6 行记录)
如果每页查询3行记录,从第3行开始:
postgres =# select * from student limit 3 offset 2;
studentid | sname | sex | birthday
-----------+-------+-----+---------------------
201003 | 王五 | 女 | 1991-10-15 00:00:00
201004 | 王凯 | 男 | 1992-11-09 00:00:00
201005 | 赵五 | 男 | 1990-05-25 00:00:00
(3 行记录)
postgres =#
postgres=# select * from test limit 3,2 ;
ERROR: LIMIT #,# syntax is not supported
LINE 1: select * from test limit 3,2;
^
HINT: Use separate LIMIT and OFFSET clauses.
postgres=#
说明:在PostgreSQL中,是不支持LIMIT 3,2 这种语法的。
Limit-offset 分页技术语法简单,使用普遍,但如果使用不当也会存在风险,譬如查询效率低。
示例:
创建一个测试表testhyl,并插入一千万条记录:
highgo=# drop table testhyl;
DROP TABLE
highgo=# create table testhyl(id serial,name varchar);
CREATE TABLE
highgo=# insert into testhyl (name) values (generate_series(1,10000000)||'hyl');
INSERT 0 10000000
highgo=#
将命令计时开关打开:
highgo=# \timing
启用计时功能.
highgo=#
下面,咱们使用limit-offset语句分别从20、2000、20000、200000、2000000开始,提取5行记录,
查看所用的时间是多少???
highgo=# select * from testhyl limit 5 offset 20;
id | name
----+-------
21 | 21hyl
22 | 22hyl
23 | 23hyl
24 | 24hyl
25 | 25hyl
(5 行记录)
时间:0.533 ms
highgo=# select * from testhyl limit 5 offset 2000;
id | name
------+---------
2001 | 2001hyl
2002 | 2002hyl
2003 | 2003hyl
2004 | 2004hyl
2005 | 2005hyl
(5 行记录)
时间:0.841 ms
highgo=# select * from testhyl limit 5 offset 20000;
id | name
-------+----------
20001 | 20001hyl
20002 | 20002hyl
20003 | 20003hyl
20004 | 20004hyl
20005 | 20005hyl
(5 行记录)
时间:2.175 ms
highgo=# select * from testhyl limit 5 offset 200000;
id | name
--------+-----------
200001 | 200001hyl
200002 | 200002hyl
200003 | 200003hyl
200004 | 200004hyl
200005 | 200005hyl
(5 行记录)
时间:13.204 ms
highgo=# select * from testhyl limit 5 offset 2000000;
id | name
---------+------------
2000001 | 2000001hyl
2000002 | 2000002hyl
2000003 | 2000003hyl
2000004 | 2000004hyl
2000005 | 2000005hyl
(5 行记录)
时间:112.091 ms
highgo=#
对testhyl表(数据条数:一千万条)
如果直接使用limit-offset进行分页,将会导致查询的性能不断下降。
说明:以上内容来源于瀚高基础软件 韩永利老师 分页技术分享部分章节,特此鸣谢!