搜索索引游标分页

搜索索引支持游标分页特性。与常规分页查询相比,游标分页可以快速定位到游标所在的数据,省去从头开始扫描大量数据并跳过的过程,在大批量导出数据时能够提供更好的性能。

前提条件

云原生多模数据库 Lindorm宽表引擎为2.8.2及以上版本。如何查看或升级当前版本,请参见升级小版本

注意事项

  • 需要确保查询语句能够命中搜索索引。如无法确定,请通过HINT显式指定使用搜索索引。关于HINT的使用,请参见HINT

  • 游标值无状态。如果两次游标分页查询之间发生了数据插入、更新或删除,最终导出的数据集可能存在数据缺失或重复。

  • 游标分页特性不支持在聚合查询上使用。

  • 游标分页特性必须结合LIMIT子句使用,LIMIT参数为当前游标页期望返回的数据量;OFFSET参数应当不设置或设置为0,如果设置为其它值,会导致当前游标页的部分数据被跳过。

  • 游标分页查询可以通过ORDER BY子句指定排序列和排序顺序,请确保排序列均为搜索索引列。如未指定排序列,则默认按照搜索索引的内部规则排序。

使用方法

  1. 创建测试数据表myTable和测试搜索索引idx

    CREATE TABLE myTable (pk INT, c1 VARCHAR, c2 INT, PRIMARY KEY(pk));
    CREATE INDEX idx USING SEARCH ON myTable (pk, c1, c2);
    UPSERT INTO myTable (pk,c1,c2) VALUES (1,'a',1);
    UPSERT INTO myTable (pk,c1,c2) VALUES (2,'b',2);
    UPSERT INTO myTable (pk,c1,c2) VALUES (3,'c',3);
    UPSERT INTO myTable (pk,c1,c2) VALUES (4,'d',4);
    UPSERT INTO myTable (pk,c1,c2) VALUES (5,'e',5);
    UPSERT INTO myTable (pk,c1,c2) VALUES (6,'f',6);
    UPSERT INTO myTable (pk,c1,c2) VALUES (7,'g',7);
    UPSERT INTO myTable (pk,c1,c2) VALUES (8,'h',8);
    UPSERT INTO myTable (pk,c1,c2) VALUES (9,'i',9);
    说明

    执行插入数据操作后,请等待约15秒,确保数据完全同步到搜索索引,再执行后续查询。

  2. 在查询语句的SELECT投影列表中添加_l_next_cursor_

    SELECT c1, c2, _l_next_cursor_ FROM myTable WHERE c2<=7 limit 3;

    该查询会匹配共7条数据,会返回其中3条。

  3. 返回的结果中,游标值将展示在_l_next_cursor_列,数据类型为VARCHAR。返回结果中的每条数据均会带有游标值,请获取最后一条数据的_l_next_cursor_值,作为查询下一页时使用的游标。

    +----+----+--------------------------+
    | c1 | c2 | _l_next_cursor_          |
    +----+----+--------------------------+
    | e  | 5  | AVd6UXlPVFE1TmpjeU9UbGQ= |
    | b  | 2  | AVd6UXlPVFE1TmpjeU9UbGQ= |
    | g  | 7  | AVd6UXlPVFE1TmpjeU9UbGQ= |
    +----+----+--------------------------+
  4. 继续查询下一页时,将上一步获取到的游标值通过WHERE子句中的_l_current_cursor_条件提供,并使用AND与其它查询条件组合。

    SELECT c1, c2, _l_next_cursor_ FROM myTable where _l_current_cursor_ = 'AVd6UXlPVFE1TmpjeU9UbGQ=' AND c2<=7 limit 3;
    +----+----+------------------------------+
    | c1 | c2 | _l_next_cursor_              |
    +----+----+------------------------------+
    | d  | 4  | AVd6RXlPRGcwT1RBeE9Ea3lYUT09 |
    | a  | 1  | AVd6RXlPRGcwT1RBeE9Ea3lYUT09 |
    | c  | 3  | AVd6RXlPRGcwT1RBeE9Ea3lYUT09 |
    +----+----+------------------------------+
    说明

    _l_current_cursor_ = '...' 条件只用作游标传递,通过AND与其它业务过滤条件组合即可,组合后不会改变原始的业务过滤条件。

  5. 重复步骤4,可以持续向前获取下一页的数据。

  6. 如果返回的_l_next_cursor_值为null,代表没有更多数据,游标查询结束。

    +----+----+-----------------+
    | c1 | c2 | _l_next_cursor_ |
    +----+----+-----------------+
    | f  | 6  | null            |
    +----+----+-----------------+

通过隐式投影方法使用

如果不希望在投影列表中增加_l_next_cursor_,也可以通过HINT的方式使用游标:

SELECT /*+ _l_allow_cursor_ */ c1, c2 FROM myTable WHERE c2<=7 limit 3;

该语法与上文的语法等效,返回的结果和其它的游标操作与上文完全相同。

下一页查询时也可以使用隐式投影方法:

SELECT /*+ _l_allow_cursor_ */ c1, c2 FROM myTable where _l_current_cursor_ = 'AVd6UXlPVFE1TmpjeU9UbGQ=' AND c2<=7 limit 3;

有关HINT的详细说明,请参考HINT