基于二级索引查询HBase表数据
功能介绍
针对添加了二级索引的用户表,您可以通过Filter来查询数据。其数据查询性能高于针对无二级索引用户表的数据查询。
- HIndex支持的Filter类型为“SingleColumnValueFilter”,“SingleColumnValueExcludeFilter”以及“SingleColumnValuePartitionFilter”。
- HIndex支持的Comparator为“BinaryComparator”,“BitComparator”,“LongComparator”,“DecimalComparator”,“DoubleComparator”,“FloatComparator”,“IntComparator”,“NullComparator”。
二级索引的使用规则如下:
- 针对某一列或者多列创建了单索引的场景下:
- 当查询时使用此列进行过滤时,不管是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)
- 当查询时使用此列进行过滤时,不管是AND还是OR操作,该索引都会被利用来提升查询性能。
- 针对多个列创建的联合索引场景下:
- 当查询时使用的列(多个),是联合索引所有对应列的一部分或者全部,且列的顺序与联合索引一致时,此索引会被利用来提升查询性能。
例如,针对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=取值范围”。
- 当查询时使用的列(多个),是联合索引所有对应列的一部分或者全部,且列的顺序与联合索引一致时,此索引会被利用来提升查询性能。
- 针对添加了二级索引的用户表,可以通过Filter来查询数据,在单列索引和复合列索引上进行过滤查询,查询结果都与无索引结果相同,且其数据查询性能高于无二级索引用户表的数据查询性能。
代码样例
下面代码片段在com.huawei.hadoop.hbase.example包的“HBaseSample”类的testScanDataByIndex方法中:
样例:使用二级索引查找数据
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"), CompareOperator.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.hindex.mapreduce.TableIndexer -Dtablename.to.index=hbase_sample_table -Dindexspecs.to.add='IDX1=>info:[name->String]' -Dindexnames.to.build='IDX1'
然后用户需要查询“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)"}