
# 创建HBase全局二级索引
在HBase数据查询场景中，当数据表存在大量数据时，基于非RowKey列的查询需要全表扫描，查询效率低下。如何在已有数据表上快速创建索引以加速条件查询？HBase全局二级索引功能允许用户在指定列上创建索引，将全表扫描转换为索引表的精确范围查询，大幅提升查询性能。本文介绍如何创建和删除HBase全局二级索引。
- **全局二级索引（Global Secondary Index，GSI）**：HBase提供的索引功能，使用独立的索引表存储索引数据。当查询条件命中索引时，可将全表扫描转换为索引表的精确范围查询，提升查询速度。
- **索引状态**：索引的生命周期状态，包括ACTIVE（可用）、INACTIVE（不可用）、BUILDING（构建中）等。空表创建的索引状态为ACTIVE，非空表创建的索引初始状态为INACTIVE，需要生成索引数据后才能变为ACTIVE。
- **覆盖列（Covered Column）**：索引表中冗余存储的数据表列。查询时如果所需数据都在覆盖列中，可直接从索引表返回结果，无需回查数据表，进一步提升查询性能。
- **预分区（Split Key）**：索引表创建时预先划分的Region分片点。合理设置预分区可以避免索引表Region成为热点，提升写入和查询性能。
- **GlobalTableIndexer工具**：HBase提供的命令行工具，用于创建、删除和管理全局二级索引。
在数据表上创建索引时，系统会创建一个独立的索引表，索引表以索引列为RowKey，存储索引列值与数据表RowKey的映射关系。当执行基于索引列的查询时，HBase先查询索引表获取匹配的RowKey列表，再根据RowKey从数据表读取完整数据。由于索引表数据量远小于数据表且按索引列有序存储，查询效率显著提升。对于非空表，创建的索引初始状态为INACTIVE，需要通过索引数据生成工具填充索引数据后，索引状态变为ACTIVE才能正常使用。
#### 场景介绍
- 在用户的表中预先存在大量数据的情况下，可以在某个列上添加索引，加速基于该列的条件查询。
- 对于未建立索引的用户表，该工具允许用户同时添加索引并构建索引数据。
 
#### 前提条件
- 已安装HBase客户端。了解如何安装客户端，请参考[安装客户端（3.x及之后版本）](https://support.huaweicloud.com/usermanual-mrs/mrs_01_0089.html)。
- 当前用户已具有创建HBase索引的权限。
 
#### 创建HBase全局二级索引
在HBase客户端执行以下命令即可添加或创建索引，执行命令后，指定的索引将被添加到表中：
```
hbase org.apache.hadoop.hbase.hindex.global.mapreduce.GlobalTableIndexer -Dtablename.to.index='table' -Dindexspecs.to.add='idx1=>cf1:[c1->string],[c2]#idx2=>cf2:[c1->string],[c2]#idx3=>cf1:[c1];cf2:[c1]' -Dindexspecs.covered.family.to.add='idx2=>cf1' -Dindexspecs.covered.to.add='idx1=>cf1:[c3],[c4]' -Dindexspecs.coveredallcolumn.to.add='idx3=>true' -Dindexspecs.splitkeys.to.set='idx1=>[\x010,\x011,\x012]#idx2=>[\x01a,\x01b,\x01c]#idx3=>[\x01d,\x01e,\x01f]'
```
参数说明如下：
- **tablename.to.inde** **x** ：表示创建索引的数据表的名称。
  当使用**tablename.to.index**创建索引时，如果数据表为空表，创建的索引状态为ACTIVE，否则索引状态为INACTIVE。
  
- **indexspecs.to.addandbuild** （可选）：表示创建时同时生成索引数据，数据表数据量较大时**不建议使用** ，建议使用索引数据生成工具生成索引数据。
  **indexspecs.to.addandbuild** 和**tablename.to.index** 不能同时使用，当使用**indexspecs.to.addandbuild**时，索引状态为BUILDING，当索引数据完整生成后，索引状态会修改为ACTIVE。
  

- **indexspecs.to.add**：表示索引名与对应数据表的列的映射（索引列定义）。
- **indexspecs.covered.to.add**（可选）：表示索引中冗余存储的数据表的列（覆盖列定义）。
- **indexspecs.covered.family.to.add**（可选）：表示索引表冗余存储的数据表的列族（覆盖列族定义）。
- **indexspecs.coveredallcolumn.to.add**（可选）：表示索引表冗余存储数据表中的所有数据（覆盖所有列）。
- **indexspecs.splitkeys.to.set** （可选）：表示索引表预分区切分点，**建议指定** ，避免索引表Region成为热点。预分区指定格式为：
  - **'#'**用于分隔索引。
  
  - splitkey包含在**'\[\]'**中。
  
  - **','** 用于分隔splitkey。
    ![](https://support.huaweicloud.com/cmpntguide-lts-mrs/public_sys-resources/note_3.0-zh-cn.png)
    预分区每个splitkey必须由**\\x01**开头。
    
   
上述命令中的参数描述如下：
- **idx1、idx2、idx3**：表示索引名称。
- **cf1、cf2**：表示列族名称。
- **c1、c2、c3、c4**：表示列名称。
- **string**：表示数据类型。支持STRING、INTEGER、FLOAT、LONG、DOUBLE、SHORT、BYTE和CHAR。
![](https://support.huaweicloud.com/cmpntguide-lts-mrs/public_sys-resources/note_3.0-zh-cn.png)
- **'#'** 用于分隔索引，**';'** 用于分隔列族，**','**用于分隔列限定符。
- 列名及其数据类型应包含在**'\[\]'**中。
- 列名及其数据类型通过**'** **-\>** **'**分隔。
- 如果未指定具体列的数据类型，则使用默认数据类型（string）。
 
**验证操作：**
索引创建完成后，可通过查询索引信息命令验证索引是否创建成功。了解如何查询HBase全局二级索引信息，请参考[查询HBase全局二级索引信息](https://support.huaweicloud.com/cmpntguide-lts-mrs/mrs_01_249222.html)。
#### 删除HBase全局二级索引
在HBase客户端执行以下命令可删除某个索引：
```
hbase org.apache.hadoop.hbase.hindex.global.mapreduce.GlobalTableIndexer -Dtablename.to.index='table'  -Dindexnames.to.drop='idx1#idx2'
```
相关参数介绍如下：
- **tablename.to.index**：表示需删除的索引所在的表名称。
- **indexnames.to.drop**：表示需要删除的索引名称，可以同时指定多个，用"#"号分隔。
**验证操作：**
索引删除完成后，可通过查询索引信息命令验证索引是否删除成功。
#### 常见问题
- **创建索引后索引状态为INACTIVE**
  当数据表非空时，使用**tablename.to.index**创建的索引初始状态为INACTIVE，表示索引表已创建但索引数据尚未生成。这是正常现象，需要通过索引数据生成工具填充索引数据后，索引状态才会变为ACTIVE。
  了解如何批量构建HBase全局二级索引数据，请参考[批量构建HBase全局二级索引数据](https://support.huaweicloud.com/cmpntguide-lts-mrs/mrs_01_249225.html)。也可以使用**indexspecs.to.addandbuild**参数在创建索引时同时生成索引数据（数据量较大时不建议使用）。
  
- **如何查询已创建的索引信息**
  创建索引后，用户可能需要查看索引的定义、状态、覆盖列等信息，以确认索引是否正确创建。
  了解如何查询HBase全局二级索引的定义及状态，请参考[查询HBase全局二级索引信息](https://support.huaweicloud.com/cmpntguide-lts-mrs/mrs_01_249222.html)。
  
- **如何修改索引状态**
  索引创建后可能需要根据业务需求调整索引状态，如将INACTIVE状态的索引启用或禁用。
  了解如何修改HBase全局二级索引状态，请参考[修改HBase全局二级索引状态](https://support.huaweicloud.com/cmpntguide-lts-mrs/mrs_01_249224.html)。
  
- **如何检查索引数据一致性**
  当查询命中的索引数据无效时，可能需要检查索引数据与数据表数据的一致性。
  了解如何检查HBase全局二级索引数据一致性，请参考[检查HBase全局二级索引数据一致性](https://support.huaweicloud.com/cmpntguide-lts-mrs/mrs_01_249226.html)。
  
- **索引创建失败**
  索引创建失败的常见原因包括：数据表不存在、索引名已存在、索引名不符合正则要求、用户没有创建索引的权限等。
  请确认数据表存在且索引名唯一。索引名需符合正则要求。确认当前用户具有创建索引的权限。
  
- **如何使用全局二级索引查询数据**
  创建索引后，用户需要通过索引查询数据以验证索引是否生效。
  了解如何基于全局二级索引查询HBase表数据，请参考[基于全局二级索引查询HBase表数据](https://support.huaweicloud.com/cmpntguide-lts-mrs/mrs_01_249228.html)。
  
 
#### 相关文档
- 了解HBase全局二级索引的工作原理和特性，请参考[HBase全局二级索引介绍](https://support.huaweicloud.com/cmpntguide-lts-mrs/mrs_01_249218.html)。
- 了解如何检查HBase全局二级索引数据一致性，请参考[检查HBase全局二级索引数据一致性](https://support.huaweicloud.com/cmpntguide-lts-mrs/mrs_01_249226.html)。
- 了解如何基于全局二级索引查询HBase表数据，请参考[基于全局二级索引查询HBase表数据](https://support.huaweicloud.com/cmpntguide-lts-mrs/mrs_01_249228.html)。
- 了解HBase常见问题，请参考[HBase常见问题](https://support.huaweicloud.com/cmpntguide-lts-mrs/mrs_01_1638.html)。
 
