
# 基于二级索引查询HBase表数据
#### 功能介绍
针对添加了二级索引的用户表，您可以通过Filter来查询数据。其数据查询性能高于针对无二级索引用户表的数据查询。
![](https://support.huaweicloud.com/devg3-mrs/public_sys-resources/note_3.0-zh-cn.png)
- 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)
    
   
- 针对多个列创建的联合索引场景下：
  - 当查询时使用的列（多个），是联合索引所有对应列的一部分或者全部，且列的顺序与联合索引一致时，此索引会被利用来提升查询性能。 例如，针对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*** **,** ***filterIfMissin** **g*** **,** ***latestVersionOnly*** **)"}**
![](https://support.huaweicloud.com/devg3-mrs/public_sys-resources/note_3.0-zh-cn.png)
**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)"}
```
