基于二级索引的查询
功能介绍
针对添加了二级索引的用户表,您可以通过Filter来查询数据。其数据查询性能高于针对无二级索引用户表的数据查询。
二级索引的使用规则如下:
针对某一列或者多列创建了单索引的场景下:
当查询时使用此列进行过滤时,不管是AND还是OR操作,该索引都会被利用来提升查询性能。 例如:Filter_Condition(IndexCol1) AND/OR Filter_Condition(IndexCol2)
当查询时使用“索引列AND非索引列”过滤时,此索引会被利用来提升查询性能。 例如:Filter_Condition(IndexCol1) AND Filter_Condition(IndexCol2) AND Filter_Condition(NonIndexCol1)
当查询时使用“索引列OR非索引列”过滤时,此索引将不会被使用,查询性能不会因为索引得到提升。 例如:Filter_Condition(IndexCol1) AND/OR Filter_Condition(IndexCol2) OR Filter_Condition(NonIndexCol1)
针对多个列创建的联合索引场景下:
当查询时使用的列(多个),是联合索引所有对应列的一部分或者全部,且列的顺序与联合索引一致时,此索引会被利用来提升查询性能。 例如,针对C1、C2、C3列创建了联合索引,生效的场景包括:
Filter_Condition(IndexCol1) AND Filter_Condition(IndexCol2) AND Filter_Condition(IndexCol3)
Filter_Condition(IndexCol1) AND Filter_Condition(IndexCol2)
Filter_Condition(IndexCol1)
不生效的场景包括:
Filter_Condition(IndexCol2) AND Filter_Condition(IndexCol3)
Filter_Condition(IndexCol1) AND Filter_Condition(IndexCol3)
Filter_Condition(IndexCol2)
Filter_Condition(IndexCol3)
当查询时使用“索引列AND非索引列”过滤时,此索引会被利用来提升查询性能。 例如:
Filter_Condition(IndexCol1) AND Filter_Condition(NonIndexCol1)
Filter_Condition(IndexCol1) AND Filter_Condition(IndexCol2) AND Filter_Condition(NonIndexCol1)
当查询时使用“索引列OR非索引列”过滤时,此索引不会被使用,查询性能不会因为索引得到提升。 例如:
Filter_Condition(IndexCol1) OR Filter_Condition(NonIndexCol1)
(Filter_Condition(IndexCol1) AND Filter_Condition(IndexCol2))OR ( Filter_Condition(NonIndexCol1))
当查询时使用多个列进行范围查询时,只有联合索引中最后一个列可指定取值范围,前面的列只能设置为“=”。 例如:针对C1、C2、C3列创建了联合索引,需要进行范围查询时,只能针对C3设置取值范围,过滤条件为“C1=XXX,C2=XXX,C3=取值范围”。
代码样例
下面代码片段在com.huawei.hadoop.hbase.example包中:
样例:使用二级索引查找数据
public void testScanDataByIndex() {
LOG.info("Entering testScanDataByIndex.");
Table table = null;
ResultScanner scanner = null;
try {
table = conn.getTable(tableName);
// Create a filter for indexed column.
Filter filter = new SingleColumnValueFilter(Bytes.toBytes("info"), Bytes.toBytes("name"),
CompareOp.EQUAL, "Li Gang".getBytes());
Scan scan = new Scan();
scan.setFilter(filter);
scanner = table.getScanner(scan);
LOG.info("Scan indexed data.");
for (Result result : scanner) {
for (Cell cell : result.rawCells()) {
LOG.info(Bytes.toString(CellUtil.cloneRow(cell)) + ":"
+ Bytes.toString(CellUtil.cloneFamily(cell)) + ","
+ Bytes.toString(CellUtil.cloneQualifier(cell)) + ","
+ Bytes.toString(CellUtil.cloneValue(cell)));
}
}
LOG.info("Scan data by index successfully.");
} catch (IOException e) {
LOG.error("Scan data by index failed.");
} finally {
if (scanner != null) {
// Close the scanner object.
scanner.close();
}
try {
if (table != null) {
table.close();
}
} catch (IOException e) {
LOG.error("Close table failed.");
}
}
LOG.info("Exiting testScanDataByIndex.");
}
注意事项
需要预先对字段name创建二级索引。
相关操作
基于二级索引表查询。
查询样例如下:
用户在hbase_sample_table的info列族的name列添加一个索引,在客户端执行,
hbase org.apache.hadoop.hbase.index.mapreduce.TableIndexer -Dtablename.to.index=hbase_sample_table -Dtable.columns.index='IDX1=>info:[name->String&100]'
然后用户需要查询“info:name”,在hbase shell执行如下命令:
>scan 'hbase_sample_table',{FILTER=>"SingleColumnValueFilter(family,qualifier,compareOp,comparator,filterIfMissing,latestVersionOnly)"}
说明:
hbase shell下面做复杂的查询请使用API进行处理。
参数说明:
- family:需要查询的列所在的列族,例如info;
- qualifier:需要查询的列,例如name;
- compareOp:比较符,例如=、>等;
- comparator:需要查找的目标值,例如binary:Zhang San;
- filterIfMissing:如果某一行不存在该列,是否过滤,默认值为false;
- latestVersionOnly:是否仅查询最新版本的值,默认值为false。
例如:
>scan 'hbase_sample_table',{FILTER=>"SingleColumnValueFilter('info','name',=,'binary:Zhang San',true,true)"}