如果常规分页查询无法满足您的业务需求,您可以在查询时设置游标分页。游标分页通过记录分页位置的方式,可以在海量数据查询场景中快速定位目标数据,减少大规模扫描带来的性能开销。本文介绍游标分页特性的使用方法和相关注意事项。
前提条件
注意事项
游标分页特性仅支持简单查询,不支持SUM、COUNT等聚合查询,也不支持包含
ORDER BY
、GROUP BY
等子句的查询。游标分页特性必须与
OFFSET
、LIMIT
子句同时使用。
功能简介
常规分页查询基于OFFSET
和LIMIT
条件在内存中过滤数据。当数据量较大时,深度分页会导致每次查询都要扫描并跳过大量数据,效率较低。
Lindorm提供了游标分页特性,支持在查询语句中指定OFFSET
、LIMIT
子句来实现分页逻辑。在执行游标分页查询时,系统可以直接根据游标快速定位到要查询数据的位置,避免扫描大量数据并跳过,从而提升大量数据场景下的查询效率。
使用方法
显式投影(推荐)
在原先分页查询的语句中添加_l_next_cursor_ 参数,即可返回下一个分页的游标。示例如下:
SELECT <column_identifier1>, <column_identifier2>, _l_next_cursor_ FROM <table_identifier> LIMIT 0, 5;
使用游标分页的查询结果会多出一列名为_l_next_cursor_
的列,列类型为VARCHAR,该列的值为下一页的游标。
需要查询下一页时,您可以在WHERE
条件中使用_l_current_cursor_
将上一页返回的游标值与原先的过滤条件(例如c1=1)通过AND带回。示例如下:
SELECT <column_identifier1>, <column_identifier2>, _l_next_cursor_ FROM <table_identifier> WHERE _l_current_cursor_ = '<游标值>' AND <过滤条件>1 LIMIT 5, 5;
隐式投影
如果您无法预先确定待查询的列名,建议您使用隐式投影。例如动态列查询场景。
当查询投影列表为*
时,默认只返回表预先定义的列,不会返回游标列。如果需要在查询时返回游标列,在SELECT
关键字后面添加HINT参数 /*+ _l_allow_cursor_ */ 即可返回下一个分页的游标。示例如下:
SELECT /*+ _l_allow_cursor_ */ * FROM <table_identifier> LIMIT 0, 5;
使用游标分页的查询结果会多出_l_next_cursor_
列,列类型为VARCHAR, 该列的值为下一页的游标。需要查询下一页时,在WHERE
条件中使用_l_current_cursor_
将上一页返回的游标值与原先的过滤条件(例如c1=1
)通过AND
带回。示例如下:
SELECT /*+ _l_allow_cursor_ */ * FROM <table_identifier> WHERE _l_current_cursor_ = '<游标值>' AND <原先的过滤条件> LIMIT 5, 5;
游标的值会随着查询结果动态变化,因此下一页的游标以当前查询结果的最后一行为准。
示例
假设示例表tb_cursor_test
的结构与表中数据如下:
-- 创建示例表
CREATE TABLE tb_cursor_test(c1 INT , c2 INT, c3 VARCHAR(50), PRIMARY KEY(c1));
-- 插入数据
UPSERT INTO tb_cursor_test(c1, c3) VALUES (1, 'c3_1'),(2, 'c3_2'),(3, 'c3_3'),(4, 'c3_4'),(5, 'c3_5');
UPSERT INTO tb_cursor_test(c1, c3) VALUES (6, 'c3_6'),(7, 'c3_7'),(8, 'c3_8'),(9, 'c3_9'),(10, 'c3_10');
UPSERT INTO tb_cursor_test(c1, c3) VALUES (11, 'c3_11'),(12, 'c3_12'),(13, 'c3_13'),(14, 'c3_14'),(15, 'c3_15');
首次执行游标分页查询。
首次执行游标分页查询时,必须在查询语句中添加_l_next_cursor_参数。
SELECT c1, c2, c3, _l_next_cursor_ FROM tb_cursor_test LIMIT 0, 5;
返回结果:
+----+------+------+------------------------------+ | c1 | c2 | c3 | _l_next_cursor_ | +----+------+------+------------------------------+ | 1 | null | c3_1 | AAAABIAAAAYFAAAABk5PUk1BTA== | | 2 | null | c3_2 | AAAABIAAAAYFAAAABk5PUk1BTA== | | 3 | null | c3_3 | AAAABIAAAAYFAAAABk5PUk1BTA== | | 4 | null | c3_4 | AAAABIAAAAYFAAAABk5PUk1BTA== | | 5 | null | c3_5 | AAAABIAAAAYFAAAABk5PUk1BTA== | +----+------+------+------------------------------+
其中,
_l_next_cursor_
列的结果AAAABIAAAAYFAAAABk5PUk1BTA==
为下一页的游标。查询第二页,需要在WHERE条件中指定第一页返回的游标。示例如下:
SELECT c1, c2, c3, _l_next_cursor_ FROM tb_cursor_test WHERE _l_current_cursor_ = 'AAAABIAAAAYFAAAABk5PUk1BTA==' LIMIT 5, 5;
返回结果:
+----+------+-------+------------------------------+ | c1 | c2 | c3 | _l_next_cursor_ | +----+------+-------+------------------------------+ | 6 | null | c3_6 | AAAABIAAAAsKAAAABk5PUk1BTA== | | 7 | null | c3_7 | AAAABIAAAAsKAAAABk5PUk1BTA== | | 8 | null | c3_8 | AAAABIAAAAsKAAAABk5PUk1BTA== | | 9 | null | c3_9 | AAAABIAAAAsKAAAABk5PUk1BTA== | | 10 | null | c3_10 | AAAABIAAAAsKAAAABk5PUk1BTA== | +----+------+-------+------------------------------+
查询第三页。示例如下:
SELECT c1, c2, c3, _l_next_cursor_ FROM tb_cursor_test WHERE _l_current_cursor_ = 'AAAABIAAAAsKAAAABk5PUk1BTA==' LIMIT 10, 5;
返回结果:
+----+------+-------+-----------------+ | c1 | c2 | c3 | _l_next_cursor_ | +----+------+-------+-----------------+ | 11 | null | c3_11 | null | | 12 | null | c3_12 | null | | 13 | null | c3_13 | null | | 14 | null | c3_14 | null | | 15 | null | c3_15 | null | +----+------+-------+-----------------+
由于仅写入了三页数据,即没有第四页数据,因此查询第三页返回的游标值为空。
- 本页导读 (1)
- 前提条件
- 注意事项
- 功能简介
- 使用方法
- 显式投影(推荐)
- 隐式投影
- 示例