
# Stream方式的Hint
#### 功能描述
指明stream使用的方法，可以为broadcast和redistribute以及指定AGG重分布的分布键。
![](https://support.huaweicloud.com/devg-dws/public_sys-resources/note_3.0-zh-cn.png)
指定Agg重分布列Hint，仅8.1.3.100及以上集群版本支持。
#### 语法格式
```
[no] broadcast | redistribute([@block_name] table_list) | redistribute ([@block_name] (*) (columns))
```
#### 参数说明
- **no**表示hint的stream方式不使用，当指定AGG分布列的hint时指定no关键字无效。
- **block_name** 表示语句块的block_name，详细说明请参考[block_name](https://support.huaweicloud.com/devg-dws/dws_04_0456.html#ZH-CN_TOPIC_0000002080515442__zh-cn_topic_0000001460722632_li99021444551)。
- **table_list** 为进行stream操作的单表或多表join结果集，见[参数说明](https://support.huaweicloud.com/devg-dws/dws_04_0457.html#ZH-CN_TOPIC_0000002116194489__zh-cn_topic_0000001510402197_section35948678143011)。
- 当指定分布列的hint时，\*为固定写法，不支持指定表名。
- **columns** 指定group by子句中的一个或者多个列，没有group by子句也可以指定distinct子句中的列。
  ![](https://support.huaweicloud.com/devg-dws/public_sys-resources/note_3.0-zh-cn.png)
  - 指定的分布列，需要用group by或distinct中的列序号或列名来表示，count（distinct）中的列只能通过列名指定。
  
  - 对于多层的查询，可以在每层指定对应层的分布列hint，只在当前层生效。
  
  - 指定的count(distinct)列仅针对生成双层hashagg的计划时才生效，否则指定的分布列无效。
  
  - 指定了分布列，如果优化器估算后发现不需要重分布，则指定的分布列无效。
    
 
#### 建议
- 通常优化器会根据统计信息选择一组不倾斜的分布键进行数据重分布。当默认选择的分布键有倾斜时，可以手动指定重分布的列，避免数据倾斜。
- 在选择分布键的时候，通常要根据数据分布特征选取一组distinct值比较高的列作为分布列，这样可以保证重分布后，数据均匀的分布到各个DN。
- 在编写好hint后，可以通过explain verbose+SQL打印执行计划，查看指定的分布键是否有效，如果指定的分布键无效会有warning提示。
 
#### 示例
- 对[示例](https://support.huaweicloud.com/devg-dws/dws_04_0455.html#ZH-CN_TOPIC_0000002053159594__zh-cn_topic_0000001658028034_section671421102912)中原语句使用如下hint：
  ```
  explain
  select /*+ no redistribute(store_sales store_returns item store) leading(((store_sales store_returns item store) customer)) */ i_product_name product_name ...
  ```
  原计划中，(store_sales store_returns item store)和customer做join时，前者做了重分布，此hint表示禁止前者混合表做重分布，但仍然保持join顺序，则生成计划如下所示：
  ![](https://support.huaweicloud.com/devg-dws/figure/zh-cn_image_0000001460882748.png "点击放大")
  
 
- 指定Agg重分布的分布列。
  ```
  explain (verbose on, costs off, nodes off)
  select /*+ redistribute ((*) (2 3)) */ a1, b1, c1, count(c1)  from t1 group by a1, b1, c1 having  count(c1) > 10 and sum(d1) > 100
  ```
  通过下面的示例可以看到指定的group by列的后两列作为分布键。
  ![](https://support.huaweicloud.com/devg-dws/figure/zh-cn_image_0000001510402789.png "点击放大")
  
- 当语句中不包含group by子句时，指定distinct列作为重分布列。
  ```
  explain (verbose on, costs off, nodes off)
  select /*+ redistribute ((*) (3 1)) */ distinct a1, b1, c1 from t1;
  ```
  ![](https://support.huaweicloud.com/devg-dws/figure/zh-cn_image_0000001460563240.png "点击放大")
  
 
