由于 MaxCompute SQL 本身不提供类似数据库的 select * from table limit x offset y 的分页查询逻辑. 但是有很多用户希望在一定场景下能够使用获取类似数据库分页的逻辑, 对查询结果进行分页 / 分批获取结果, 本文将介绍几种方法, 来实现上述场景.
1. 借助 row_number()函数作为递增唯一标识进行过滤查询
select*from(selectrow_number()over()asrow_id,*fromorders_delta)twhererow_idbetween10and20;
通过 row_number()对数据进行排序及唯一标识编号, 然后根据该标识选取每次查询的分页范围.
2. 利用 Java SDK 的 InstanceTunnel 在下载结果时进行分批下载
MaxCompute JavaSDK 提供了 SQLTask + InstanceTunnel 直接导出 select 的数据集的方法, 具体可以参考《使用 Instance Tunnel 获取 Maxcompute Instance 的执行结果》
该案例中, 提供了通过 InstanceTunnel 来下载用户自定义 SELECT 查询的方法.
- Odps odps = OdpsUtils.newDefaultOdps(); // 初始化 Odps 对象
- Instance i = SQLTask.run(odps, "select * from wc_in;");
- i.waitForSuccess();
- // 创建 InstanceTunnel
- InstanceTunnel tunnel = new InstanceTunnel(odps);
- // 根据 instance id, 创建 DownloadSession
- InstanceTunnel.DownloadSession session = tunnel.createDownloadSession(odps.getDefaultProject(), i.getId());
- long count = session.getRecordCount();
- // 输出结果条数
- System.out.println(count);
- // 获取数据的写法与 TableTunnel 一样
- TunnelRecordReader reader = session. openRecordReader (0, count);
- Record record;
- while ((record = reader.read()) != null) {
- for (int col = 0; col < session.getSchema().getColumns().size(); ++col) {
- // wc_in 表字段均为 STRING, 这里就直接打印输出
- System.out.println(record.get(col));
- }
- }
- reader.close();
这里通过了 SQLTask 提交了 1 条自定义 select 查询, 然后使用 InstanceTunnel.DownloadSession 直接对该查询结果进行下载. 其中, openRecordReader 方法支持指定本次读取记录的起始位置和读取数量, 通过 openRecordReader(start,long)的参数设定, 可实现分批下载的逻辑.
例如, 将上面例子中 openRecordReader (0, count)修改为用户想获取的起始位置和获取记录数量:
TunnelRecordReader reader = downloadSession.openRecordReader(100, 20);
参考内容: MaxCompute SDK Java Doc 的 InstanceTunnel.DownloadSession 类的 openRecordReader 方法.
由于 MaxCompute 所处理表的数据量往往都非常大, 以上的方法一般不建议使用在报表的交互分页查询场景上. 对于交互时查询有需求的用户, 可以考虑通过 MaxCompute 的交互式分析 (Lightning) 来查询.
3. 利用 MaxCompute 交互式分析 (Lightning) 的 limit/offset 语法实现分页
MaxComput SQL 不支持 limit/offset 语法, 但开发者可以借助 MaxCompute 交互式分析 (Lightning) 来使用 limit/offset.
MaxCompute 交互式分析能够在相同的权限体系下, 以 PostgreSQL 协议和语法快速查询 MaxCompute 数据. 利用 PostgreSQL 的 limit offset 语法可以实现与数据库查询相同的分页效果.
来源: https://yq.aliyun.com/articles/696953