最近在性能调查中,发现很多性能问题都是由于逻辑不当,造成SQL性能下降。
1. 在写SQL的时候最好能够减少不必要的查询。
比如有一个检索是显示自己权限组织内的所有人的资格数量(每页显示20人)。
发现的做法如下:
首先,先取出自己权限组织的所以人的用户ID
然后,select 用户名, count(userid) as 资格数量 from comp where userid in (上面取得的所有用户id) group by userid order by username limit 21 offset 0
这边如果自己的权限组织的人只有几个,几十个,几百个都还好。如果是上万个的话太不可思议了。
光是debug log里面的就是几十kb的数据。SQL的速度自然也好不到哪里去。
这个地方的实现不应该是先取得所以的人,然后查询。而是动态子查询比较好。
实际上这个地方如果资格数量不是排序项目的话,我们可以分开来写。
第一步:先取得权限组织内的所以用户的基本信息。(除了资格数量一个项目外的所有项目。)
select 用户名,其他项目 from comp where 权限组织用户 order by username limit 21 offset 0
第二步:取得21条数据的资格数量
select 用户id, count(userid) as 资格数量 from comp where userid in (上面取得的所有用户id)
这样改造后速度是上升很多。大概在1s左右。改造前需要十几秒。
由此知道,数据库的性能不完全是数据库产品,如果编程人员对付着写代码的话,想得到性能好的系统那是很奢望的一件事情。
2. 尽量减少临时表的数量
在查询中经常不会只是一张表。而会是很多张。但是如果过多的话,数据库的性能会大幅度下降。PostgreSQL貌似最好不要超过7张表。
比如在or的查询中,如果可以的话改为union来减少临时表的数量。