最近在项目上遇到一个SQL问题,觉得挺有意思的,在这里给大家分享下。事情的发生是这样的:突然有一天发现项目中数据库Postgresql的一个主要的表(数据量也很大)相关的SQL session都非常慢,即使是随便一个查询语句也是这样。以下是对排查问题过程的总结。


1)遇到这样的问题,第一反应就是查看当前数据库中活跃的sql session都有哪些?可以通过如下语句进行查找:

select * from pg_stat_activity where state = 'active';

查找到这些结果之后,做一个简单的归纳总结,比如哪些SQL的比例占大数。通过查找发现,活跃的SQL session并不是很多,只是绝大数和系统的一个主表有关联。

2) 发现相关的SQL,分别是简单的select,delete:

select * from table_name where xx_id = 'xxx';delete from table_name where xx_id = 'xxx';

这种SQL从结构上看,真的是非常简单,不应该出现很长时间不返回结果的情况。是不是数据库CPU在此时比较忙碌?


3)检查数据库资源消耗情况,发现数据库资源情况很好,CPU使用率只有20%左右,那么回到第2步,继续进行问题排查。

4)仔细发现"xx_id" 这个字段没有添加index,并且此表由于是业务的主表,数据量很大,所以查找会全表扫描。其实delete语句也是一样,如果是加where子句的delete或者update,子句中的筛查字段如果加index效率还是比不加index要好。

5)通过SQL的执行计划也可以印证这一点。select 语句比较慢,CPU是在等待磁盘io的结果返回,所以数据库磁盘统计数据(读操作也是比较频繁的)。

6)通过讨论,解决方案就是在xx_id上添加索引,并且添加必要的filter条件,特别是主表主键相关

PostgreSQL SQL调优案例实录_数据库调优