mysql 查询 优化 实例,MySQL关联查询优化实例

项目中发现有一个查询响应非常慢,花时间分析以及优化,特地记录。

(1)背景

项目采用MySQL数据库,操作使用Ibatis;

(2)查询说明

这个查询是每次查询一定数目的用户信息,查询中涉及到多表关联,具体查询SQL如下

SELECT S.NAME as name,

S.IMAGE as image,

S.ID as id,

C.NAME as companyName,

C.ID as companyId,

A.FILE_NAME AS resourceFileName,

A.FILE_PATH AS resourceFilePath,

A.FILE_ID AS resourceFileId,

COUNT(R.CONTACT) AS updResourceSize

from sys_user_info S

LEFT JOIN ATTACH_FILE_INFO A ON S.ID = A.USER_ID

LEFT JOIN

(SELECT RESOURCE_ID,CONTACT FROM company_resource_info

WHERE UPDTIME >= #UPDResourceTime:TIMESTAMP# ) R

ON S.ID = R.CONTACT,

company_info C

WHERE S.COMPANY_ID = C.ID

GROUP BY S.ID

LIMIT 15

注意其中用到了子查询,涉及到临时表

(3)分析过程

使用MySQL自带的profiler分析结果如下图

0818b9ca8b590ca3270a3433284dd417.png

观察可得,99%的时间花在了拷贝数据到临时表上,也就是与其中的子查询有关系。

想来奇怪,如果只是LIMIT 15条数据,临时数据不应该花费这么多时间;个人觉得问题应该出在LIMIT对于里面的子查询无效,也就是里面的子查询会涉及到全部数据,从而导致临时表消耗很大的时间,这样就不难理解了。

(4)优化

想清楚了上面的原因,解决的思路也就比较清楚了,只要让里面涉及的子查询只查LIMIT对应的数据就可以了。

重新实行的方式如下:

select="steel_userCompany.selectUpdResourceSize" />

resultClass="int">

SELECT COUNT(1) FROM company_resource_info

WHERE CONTACT = #CONTACT#

and UPDTIME >= #UPDResourceTime:TIMESTAMP#

SELECT S.NAME as name,

S.IMAGE as image,

S.ID as id,

C.NAME as companyName,

C.ID as companyId,

A.FILE_NAME AS resourceFileName,

A.FILE_PATH AS resourceFilePath,

A.FILE_ID AS resourceFileId,

#UPDResourceTime:TIMESTAMP# as UPDResourceTime

from sys_user_info S

LEFT JOIN ATTACH_FILE_INFO A ON S.ID = A.USER_ID

LEFT JOIN company_info C ON S.COMPANY_ID = C.ID

LIMIT 15

主要的做法就是,每次先查出LIMIT 15条不含子查询结果的数据,定义一个resultMap映射结果集,针对每一条记录再去分别调用一次查询从而得到最后想要的结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值