分页查询

要一次遍历一个表的一页结果(也称为分页),有两个选项,建议只使用其中一个:

  • 键集分页(快速,推荐)
  • LIMIT/OFFSET分页(慢,不推荐)

键集分页

Keyset分页(也称为seek方法)用于从表中快速获取记录的子集。它通过限制使用WHERELIMIT子句组合返回的记录集来做到这一点。要获取下一页,请检查WHERE子句中列的值与上一页结果中返回的最后一行的值。

键集分页查询的一般模式是:

SELECT * FROM test AS OF SYSTEM TIME ${time}
  WHERE key > ${value}
  ORDER BY key
  LIMIT ${amount}

这比使用LIMIT更快,因为键集分页查询OFFSET不是对值进行全表扫描,而是为每次迭代查看固定大小的记录集。如果子句中用于实现分页的键是索引的且唯一,则可以快速完成此操作。

举例

建表并插入数据:

create table cust_info(
    cust_no       string primary key,
    cust_name     varchar(30) not null,
    cust_card_no  varchar(18),  
    cust_phoneno  decimal(15),
    cust_address  varchar(30),
    cust_type     varchar(10),
    index(cust_card_no)
 );
 
insert into cust_info values('14435550','王吉','12022519960321531X',15122511874,'天津武清','抵押');
insert into cust_info values('14435551','张贺','431256197306265320',15534343555,'山西临汾','质押');
insert into cust_info values('14435552','刘明','371452199303034312',18967756743,'陕西延安','信用');
insert into cust_info values('14435553','李华','52112119860621421X',15833355455,'湖北武汉','抵押');
insert into cust_info values('14435554','郑青','213456199102275341',13054546567,'江西南昌','质押');

查询示例:

select * from cust_info limit 3;
   cust_no  | cust_name |    cust_card_no    | cust_phoneno | cust_address | cust_type
-----------+-----------+--------------------+--------------+--------------+------------
  14435550 | 王吉      | 12022519960321531X |  15122511874 | 天津武清     | 抵押
  14435551 | 张贺      | 431256197306265320 |  15534343555 | 山西临汾     | 质押
  14435552 | 刘明      | 371452199303034312 |  18967756743 | 陕西延安     | 信用
select * from cust_info limit 3 offset 3;
  cust_no  | cust_name |    cust_card_no    | cust_phoneno | cust_address | cust_type
-----------+-----------+--------------------+--------------+--------------+------------
  14435553 | 李华      | 52112119860621421X |  15833355455 | 湖北武汉     | 抵押
  14435554 | 郑青      | 213456199102275341 |  13054546567 | 江西南昌     | 质押

由此可见,先执行数据的offset取消,在执行limit限制。

性能比较

在查询大量相同数据时候,使用LIMIT/OFFSET进行分页的查询慢,所以不推荐使用,具体可以结合explain使用执行计划进行查看。