最近做的公司的项目,主要负责和移动端交互后台,有一个接口返回时间7 秒,一个20 秒;项目结构是springMVC 和hibernate ,hibernate觉得查询多还可以,但是添加删除更新多,又是 夺标关联,映射,就很慢了;这是慢的一个小原因;
现在说一个接口 ,answer 表 ,录音表 ,会有很多录音; 评论表 answer_comment,对录音的评论,关联字段 answer_id ; 一条录音有多条评论,
第一个接口;查录音answer表, 把 所有没被评论的分页查询出来按时间排序, 实现是这样, 把 所有的common的表 answer_id 去拿出来,和answer表比较,
以前的sql : select * from answer a where a.id not in(select b.answer_id from answer b) and a.....
没有的查出来,如果数据量小,可以接受,现在线上 数据,录音多,评论也多,这种时间负责度 为n 的平方,就会特别慢,我用exists 替换了in ,不行,加了索引也不行,
解决办法:answer表加个 字段是否已 被评论 flag ,先把 线上数据用sql更新 update answer a set a.isComment=1 where EXISTS(select 1 from answer_comment b where b.answer_id=a.id);
然后程序Java控制,如果有评论,就把那条录音isComment 更新为1 ,这样查询 就是单表查询,不会有关联了 ,时间 复杂度为1 ;sql :select a from answer a where a.isComment=1;
第二个接口:返回高分录音 同样是answer 表, answer_Comment , 用户对录音的点评 分为四个维度存在 answer_Comment ,高分录音是4 个维度求和 大于3 的算高分;
之前的sql:select * from answer a group by a.id having a.id in (select c. answer_id avg(c.1+c.2+c.3+c.4) >3 from answer_Comment c ) and a.sum(secounds)>100 这里也是求和 和in 执行时间很慢
大约20 秒了,当我接受这个项目的时候,添加索引 或者基本的sql优化也回力无天,这里又是 计算,又是in ;
解决 办法,还是添加字段,但是这个 计算是实时 的,多了一条评论, 积分 就会改变 ,这里应为 才用了存储过程,每天晚上去统计计算情况在answer表加一个字段 , 平均分, 更新后,类似于第一个接口 ;
=====================================================================================================================
其实sql 优化那些查询,网上那些办法,什么查询结果需要的字段啊 ,加索引啊,都是空话,我觉得关键在于表的设计 ,尽量减少多表交互太多, 当然不是单表;