
# SQL执行很慢，性能低，有时长时间运行未结束
#### 问题现象
SQL执行很慢，性能低，有时长时间运行未结束。
#### 原因分析
SQL运行慢可从以下几方面进行分析：
1. 使用EXPLAIN命令查看SQL执行计划，根据执行计划判断是否需要进行SQL调优。
2. 分析查询是否被阻塞，导致语句运行时间过长，可以强制结束有问题的会话。
3. 审视和修改表定义。选择合适的分布列，避免数据倾斜。
4. 分析SQL语句是否使用了不下推的函数，建议更换为支持下推的语法或函数。
5. 对表定期执行VACUUM FULL和ANALYZE操作，可回收已更新或已删除的数据所占据的磁盘空间。
6. 检查表有无索引支撑，建议例行重建索引。 数据库经过多次删除操作后，索引页面上的索引键将被删除，造成索引膨胀。例行重建索引，可有效的提高查询效率。
   
7. 对业务进行优化，分析能否将大表进行分表设计。
 
#### 处理方法
DWS提供了分析查询和改进查询的方法，并且为用户提供了一些常见案例以及错误处理办法。您可以参考[性能调优](https://support.huaweicloud.com/devg-dws/dws_04_0401.html)章节对SQL进行性能调优。常见问题也可以优先参考以下两种方法进行分析：
- 方法一：对表定期做统计优化查询。
  如果频繁对表执行INSERT语句插入数据，需要定期对表执行ANALYZE：
  ```
  ANALYZE table_name;
  ```
  如果频繁对表执行DELETE语句删除数据，需要定期对表执行VACUUM FULL：
  ```
  VACUUM FULL table_name;
  ```
  ![](https://support.huaweicloud.com/trouble-dws/public_sys-resources/note_3.0-zh-cn.png)
  执行VACUUM FULL语句时需选择空闲时间窗或停止业务时操作。
  查询表大小，如果表非常大，而实际只有很少数据，那么应该执行VACUUM FULL对表进行磁盘碎片整理。
  ```
  SELECT * FROM pg_size_pretty(pg_table_size('tablename'));
  VACUUM FULL table_name;
  ```
  
方法二：通过PGXC_STAT_ACTIVITY视图查询正在运行的SQL语句信息。
1. 查看当前正在运行（非idle）的SQL信息： 
   ```
   SELECT coorname, pid,datname,usename,state,waiting,query FROM pgxc_stat_activity WHERE state <> 'idle';
   ```
   
   
2. 查看当前处于阻塞状态的查询语句：
   
   ```
   SELECT coorname, pid,datname, usename, state,waiting,query FROM pgxc_stat_activity WHERE state <> 'idle' and waiting=true;
   ```
   
   
3. 判断查询语句是否阻塞。 
   - 如果没有阻塞，查找相关业务表，按照[方法一]中的建议方法进行处理。
   
   - 如果存在语句阻塞，根据所查找的问题会话的线程ID，结束阻塞的执行语句。其中cn_5001、pid替换成[2]查到的coorname和pid实际对应值。
     ```
     execute direct on (cn_5001) 'SELECT pg_terminate_backend(pid)';
     ```
     
   
   
   
   
 
