
# 行数估算过小，优化器选择走NestLoop导致性能下降
#### 问题现象
查询语句执行慢，卡住无法返回结果。SQL语句的特点是2\~3张表left join，然后通过SELECT查询结果，执行计划如下：
![](https://support.huaweicloud.com/trouble-dws/figure/zh-cn_image_0000001163632837.png "点击放大")
#### 原因分析
优化器在选择执行计划时，对结果集评估较小，导致执行计划走了NestLoop，性能下降。
#### 分析过程
1. 排查当前的I/O、内存、CPU使用情况，没有发现资源占用高的情况。
2. 查看慢SQL的线程等待状态。 
   根据线程等待状态，并没有出现都在等待某个DN的情况，初步排除中间结果集偏斜到了同一个DN的情况。
   ```
   SELECT * FROM pg_thread_wait_status WHERE query_id='149181737656737395';
   ```
   ![](https://support.huaweicloud.com/trouble-dws/figure/zh-cn_image_0000001163633745.png "点击放大")
   
   
3. 联系运维人员登录到相应的实例节点上，打印等待状态为none的线程堆栈信息如下。 
   通过反复打印堆栈信息，发现堆栈在变化，并没有hang死，所以初步判断该问题为性能慢的问题。另堆栈中有VecNestLoopRuntime，结合执行计划，初步判断是由于统计信息不准，优化器评估结果集较少，执行计划使用了NestLoop导致性能下降。
   **gstack** *14104*
   ![](https://support.huaweicloud.com/trouble-dws/figure/zh-cn_image_0000001117396854.png "点击放大")
   ![](https://support.huaweicloud.com/trouble-dws/figure/zh-cn_image_0000001163637163.png "点击放大")
   
   
4. 对表执行ANALYZE后性能并没有太大改善。
5. 对SQL增加hint关闭索引，让优化器强行使用hashjoin，发现hint功能没有生效，原因是hint无法改变子查询中的计划。
6. 通过SET enable_indexscan = off，执行计划被改变，使用了Hash Left Join，慢SQL在3秒左右返回结果，查询性能恢复。 
   ![](https://support.huaweicloud.com/trouble-dws/figure/zh-cn_image_0000001119758952.png "点击放大")
   
   
 
#### 处理方法
通过**set enable_indexscan = off**关闭索引功能，让优化器生成的执行计划不走NestLoop，而走Hashjoin。
