-
Notifications
You must be signed in to change notification settings - Fork 24
查询接口
Shen Yunlong edited this page Aug 8, 2023
·
8 revisions
查询接口支持根据主键或者主键的范围进行扫描,也可以不指定主键,根据索引或者索引前缀范围进行扫描查询,同时可以对非主键列指定过滤条件,只有满足条件的行才会返回。
下面是两个查询的例子:
- 查询 test_table表 c2, c3 列,主键范围为 1000 <= c1 <= 2000,并且c2 == 0,c3 > 100 的数据行
// create table test_table(c1 int, c2 int, c3 int, primary key(c1)) partition by key(a) partitions 16;
int rowkeyStart = 1000L;
int rowkeyEnd = 2000L;
QueryResultSet resultSet = obTableClient.query("test_table")
.select("c2","c3")
.setScanRangeColumn("c1")
.addScanRange(rowkeyStart, rowkeyEnd)
.setFilter(andList(compareVal(ObCompareOp.EQ, "c2", 0),
compareVal(ObCompareOp.GT, "c3", 100)))
.execute();
for (int i = 0; i < resultSet.cacheSize(); i++) {
resultSet.next();
Map<String, Object> row = resultSet.getRow();
for (Map.Entry<String, Object> entry : row.entrySet()) {
System.out.println(entry.getKey() + "," + entry.getValue());
}
}
- 查询 test_index表 c1, c2 列,索引范围为 c1 == 0, 2 <= c3 <=40,并且c4 > 100 的数据行
// create table test_index(c1 int, c2 int, c3 int, c4 int, primary key(c1, c2), index idx1(c1, c3)) local) partition by key(c1) partitions 16;
QueryResultSet resultSet = obTableClient.query("test_index")
.select("c1","c2")
.setScanRangeColumn('c1', "c3")
.indexName("c1_c3_idx")
.addScanRange(new Object[]{0, 2}, new Object[]{0, 40})
.setFilter(compareVal(ObCompareOp.GT, "c4", 100))
.execute();
for (int i = 0; i < resultSet.cacheSize(); i++) {
resultSet.next();
Map<String, Object> row = resultSet.getRow();
for (Map.Entry<String, Object> entry : row.entrySet()) {
System.out.println(entry.getKey() + "," + entry.getValue());
}
}
每次查询需要指定返回结果的列(投影列),可以通过如下接口设置返回一列或者多列: TableQuery select(String... columns);
每次查询需要设置查询扫描列,并添加至少一个查询扫描范围,可以是主键或者主键前缀范围,索引或者索引前缀范围,table api 会基于查询扫描范围进行路由选择,避免发送请求到不必要的 observer 节点上,同时查询扫描范围还会被下推到存储,以提升查询执行的性能,添加查询扫描的接口如下:
TableQuery setScanRangeColumns(String... columns);
TableQuery addScanRange(Object start, Object end);
TableQuery addScanRange(Object[] start, Object[] end);
TableQuery addScanRange(Object start, boolean startEquals, Object end, boolean endEquals);
TableQuery addScanRange(Object[] start, boolean startEquals, Object[] end, boolean endEquals);
- start:扫描范围的起点
- end:扫描范围的终点
- startEquals:扫描范围是否包含 start,不带该参数的接口默认是包含
- endEquals:扫描范围是否包含 end,不带该参数的接口默认是包含
通过 compareVal 可以定义某列的过滤条件,compareVal 的定义如下:
public static ObTableValueFilter compareVal(ObCompareOp op, String columnName, Object value)
- compareOp:比较操作符,目前支持 LT, GT, LE, GE, NE, EQ, IS, IS_NOT 8 种
- columnName:指定比较的列名
- value:指定比较值
查询默认使用主键索引进行扫描,同时通过显式指定索引名字来使用特定索引,此时查询扫描范围也是索引或者索引前缀的范围。
TableQuery indexName(String indexName);
- 当使用索引进行扫描的时(主键也可以看作索引),在每个 observer 分区返回的结果集是索引序的,如果查询的扫描范围只涉及到一个分区,那么返回给客户端结果集也是索引序的。
- 因为当前 Table API 只支持局部索引,所以当查询范围涉及多个分区的时候,无法保证返回给客户端的结果是整体有序的,在(observer 4.1)支持的全局索引可以实现该功能。
通过 Limit 可以限制返回的结果集行数(limit),以及跳过的结果集行数(offset),类似 SQL 的 limit m, n 语句,通过指定 limit 可以实现分页查询。
TableQuery limit(int limit);
TableQuery limit(int offset, int limit);
TableQuery scanOrder(boolean forward);
默认情况下,如果不指定 scanOrder,那么默认就是 forward(从前向后)