
# 使用Hive CBO功能优化多表查询效率
#### 操作场景
在Hive中执行多表Join时，Hive支持开启CBO（Cost Based Optimization），系统会自动根据表的统计信息，例如数据量、文件数等，选出合适计划提高多表Join的效率。Hive需要先收集表的统计信息后才能使CBO正确的优化。
- CBO优化器会基于统计信息和查询条件，尽可能地使Join顺序达到更优。但是也可能存在特殊情况导致Join顺序调整不准确。例如数据存在倾斜，以及查询条件值在表中不存在等场景，可能调整出非优化的Join顺序。
- 开启列统计信息自动收集时，需要在Reduce侧做聚合统计。对于没有Reduce阶段的insert任务，将会多出Reduce阶段，用于收集统计信息。
 
#### 前提条件
已登录Hive客户端，具体操作请参见[Hive客户端使用实践](https://support.huaweicloud.com/cmpntguide-lts-mrs/mrs_01_0952.html)。
#### 操作步骤
1. 登录FusionInsight Manager界面，选择"集群 \> 服务 \> Hive \> 配置"。
2. 在搜索框中搜索"hive.cbo.enable"参数，将值修改为"true"永久开启CBO功能，保存配置并重启受影响的实例使配置生效。 
   ![](https://support.huaweicloud.com/cmpntguide-lts-mrs/zh-cn_image_0000001724866997.png "点击放大")
   
   
3. 手动收集Hive表已有数据的统计信息。 
   执行以下命令，可以手动收集统计信息。仅支持统计一张表，如果需要统计不同的表需重复执行。
   ```
   ANALYZE TABLE [db_name.]tablename [PARTITION(partcol1[=val1], partcol2[=val2], ...)]
   COMPUTE STATISTICS
   [FOR COLUMNS]
   [NOSCAN];
   ```
   其中：
   - 指定FOR COLUMNS时，收集列级别的统计信息。
   
   - 指定NOSCAN时，将只统计文件大小和个数，不扫描具体文件。
   
   
   例如：
   **analyze table table_name compute statistics;**
   **analyze table table_name compute statistics for columns;**
   
   
4. 配置Hive自动收集统计信息。开启配置后，执行**insert overwrite/into** 命令插入数据时才自动统计新数据的信息。
   
   - 在Hive客户端执行以下命令临时开启收集： 开启表/分区级别的统计信息自动收集：
     **set hive.stats.autogather = true;**
     开启列级别的统计信息自动收集：
     **set hive.stats.column.autogather = true;**
     ![](https://support.huaweicloud.com/cmpntguide-lts-mrs/public_sys-resources/note_3.0-zh-cn.png)
     - 列级别统计信息的收集不支持复杂的数据类型，例如Map，Struct等。
     
     - 表级别统计信息的自动收集不支持Hive on HBase表。
       
   
   
   
   - 在Manager界面Hive的服务配置中，搜索参数"hive.stats.autogather"和"hive.stats.column.autogather"，修改参数值为"true"永久开启收集功能。
   
   
   
   
5. 执行以下命令可以查看统计信息。 
   **DESCRIBE FORMATTED table_name\[.column_name\] PARTITION partition_spec;**
   例如：
   **desc formatted table_name;**
   **desc formatted table_name id;**
   **desc formatted table_name partition(time='2016-05-27');**
   ![](https://support.huaweicloud.com/cmpntguide-lts-mrs/public_sys-resources/note_3.0-zh-cn.png)
   分区表仅支持分区级别的统计信息收集，因此分区表需要指定分区来查询统计信息。
   
   
 
