
# 优化Hive"窗口函数 + LIMIT"模式SQL查询性能
#### 操作场景
当执行的Hive SQL脚本包含"窗口函数 + LIMIT" 模式时（常见于去重、取TopN等场景），可能会遇到作业运行异常缓慢的情况。例如，典型的SQL模式为：
```
SELECT ... FROM (  SELECT ...,  RANK() OVER (PARTITION BY 分区字段 ORDER BY 排序字段) as rn   FROM ...) T WHERE rn <= N; --或者ROW NUMBER(), DENSE_RANK()窗口函数
```
该类作业运行后，可能会在后台频繁打印"Top-N hash is flushing rows"日志，产生该问题的根因如下：
- 窗口计算原理： 为了计算每个分区的TopN，引擎必须在内存中为每一个独立的分区键维护一个独立的计算单元。
- 内存耗尽： 如果PARTITION BY字段（如用户ID、手机号、订单号等）有数百万甚至更多不同的值，就会创建海量的计算单元，迅速耗尽分配的内存。
- 性能瓶颈： 内存耗尽后，引擎会频繁地在内存和磁盘之间来回刷写数据，以释放空间。管理刷写过程的算法在分区数极大时效率会下降，导致作业大部分时间浪费在内存管理上，而非实际计算。
 
#### "窗口函数 + LIMIT"模式SQL查询性能优化
可通过调整Hive的"hive.limit.pushdown.memory.usage"参数，以显著提升"窗口函数 + LIMIT"模式作业的执行效率。该参数控制了用于执行窗口函数Limit优化操作的最大内存比例，默认值（0.1）通常较小，在面对高基数分区键时可能不够使用。可在对应SQL脚本最前面添加以下SET语句修改"hive.limit.pushdown.memory.usage"的值，推荐设置该参数值的范围为0.3\~0.5：
```
--推荐方案：将更多内存分配给TopN计算
SET hive.limit.pushdown.memory.usage = 0.3;
```
修改该参数值后，可达到以下效果：
- 提升性能： 增大了可用内存池，减少了频繁的磁盘刷写次数，从而大幅度缩短作业运行时间。
- 维持优化： 避免了引擎因内存不足而完全禁用TopN优化特性，确保了计算效率。
- 参数权衡： 该参数值并非越大越好，设置过高可能会挤占任务计算需要的内存，需根据实际情况调整。
 
