`

MySQL关联查询优化实例

 
阅读更多
原文地址:http://www.linuxidc.com/Linux/2011-11/46585.htm



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

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

(2)查询说明

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

<select id="select"  parameterClass="UserCompany" resultClass="UserCompany">  
                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 
    </select> 
注意其中用到了子查询,涉及到临时表
(3)分析过程

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



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

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

(4)优化

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

重新实行的方式如下:

<resultMap class="cn.com.steel.wuyou.model.UserCompany" id="UserCompanyMap"> 
        <result property="name" column="name" /> 
        <result property="image" column="image" /> 
        <result property="id" column="id" /> 
        <result property="companyName" column="companyName" /> 
        <result property="companyId" column="companyId" /> 
        <result property="resourceFileName" column="resourceFileName" /> 
        <result property="resourceFilePath" column="resourceFilePath" /> 
        <result property="resourceFileId" column="resourceFileId" /> 
        <result property="UPDResourceTime" column="UPDResourceTime" /> 
        <result property="updResourceSize" column="{CONTACT=id,udpResourceTime=UPDResourceTime}" 
            select="steel_userCompany.selectUpdResourceSize" /> 
    </resultMap> 
 
    <select id="selectUpdResourceSize" parameterClass="java.util.HashMap" 
        resultClass="int"> 
        SELECT COUNT(1) FROM company_resource_info 
        WHERE CONTACT = #CONTACT# 
        and UPDTIME >= #UPDResourceTime:TIMESTAMP# 
    </select> 
 
 
    <select id="select" parameterClass="UserCompany" resultMap="UserCompanyMap"> 
        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 
    </select> 
主要的做法就是,每次先查出LIMIT 15条不含子查询结果的数据,定义一个resultMap映射结果集,针对每一条记录再去分别调用一次查询从而得到最后想要的结果。 linux
分享到:
评论

相关推荐

    mysql关联子查询的一种优化方法分析

    本文实例讲述了mysql关联子查询的一种优化方法。分享给大家供大家参考,具体如下: 很多时候,在mysql上实现的子查询的性能较差,这听起来实在有点难过。特别有时候,用到IN()子查询语句时,对于上了某种数量级的表...

    MySQL联合索引功能与用法实例分析

    本文实例讲述了MySQL联合索引功能与用法。分享给大家供大家参考,具体如下: 联合索引又叫复合索引。对于复合索引:Mysql从左到右的使用索引中的字段,一个查询可以只使用索引中的一部份,但只能是最左侧部分。例如...

    MySQL 5.1中文手冊

    7.2.11. MySQL如何简化外部联合 7.2.12. MySQL如何优化ORDER BY 7.2.13. MySQL如何优化GROUP BY 7.2.14. MySQL如何优化LIMIT 7.2.15. 如何避免表扫描 7.2.16. INSERT语句的速度 7.2.17. UPDATE语句的速度 7.2.18. ...

    MySql 5.1 参考手册.chm

    7.2.11. MySQL如何简化外部联合 7.2.12. MySQL如何优化ORDER BY 7.2.13. MySQL如何优化GROUP BY 7.2.14. MySQL如何优化LIMIT 7.2.15. 如何避免表扫描 7.2.16. INSERT语句的速度 7.2.17. UPDATE语句的速度 7.2.18. ...

    MySQL 5.1参考手册

    7.2.11. MySQL如何简化外部联合 7.2.12. MySQL如何优化ORDER BY 7.2.13. MySQL如何优化GROUP BY 7.2.14. MySQL如何优化LIMIT 7.2.15. 如何避免表扫描 7.2.16. INSERT语句的速度 7.2.17. UPDATE语句的速度 ...

    MySQL中表子查询与关联子查询的基础学习教程

    MySQL 表子查询实例 下面是用于例子的两张原始数据表: article 表: blog 表: SQL 如下: SELECT * FROM article WHERE (title,content,uid) IN (SELECT title,content,uid FROM blog) 查询返回结果如下所示...

    MYSQL中文手册

    7.2.11. MySQL如何简化外部联合 7.2.12. MySQL如何优化ORDER BY 7.2.13. MySQL如何优化GROUP BY 7.2.14. MySQL如何优化LIMIT 7.2.15. 如何避免表扫描 7.2.16. INSERT语句的速度 7.2.17. UPDATE语句的速度 ...

    MySQL查询优化:用子查询代替非主键连接查询实例介绍

    对多的两张表,一般是一张表的外键关联到另一个表的主键,接下来为大家介绍下用子查询代替非主键连接查询,感兴趣的朋友可以参考下哈,希望对你有所帮助

    MySQL 5.1官方简体中文参考手册

    7.2.11. MySQL如何简化外部联合 7.2.12. MySQL如何优化ORDER BY 7.2.13. MySQL如何优化GROUP BY 7.2.14. MySQL如何优化LIMIT 7.2.15. 如何避免表扫描 7.2.16. INSERT语句的速度 7.2.17. UPDATE语句的速度 7.2.18. ...

    MySQL 5.1参考手册中文版

    7.2.11. MySQL如何简化外部联合 7.2.12. MySQL如何优化ORDER BY 7.2.13. MySQL如何优化GROUP BY 7.2.14. MySQL如何优化LIMIT 7.2.15. 如何避免表扫描 7.2.16. INSERT语句的速度 7.2.17. UPDATE语句的速度 ...

    MySQL 5.1参考手册 (中文版)

    7.2.11. MySQL如何简化外部联合 7.2.12. MySQL如何优化ORDER BY 7.2.13. MySQL如何优化GROUP BY 7.2.14. MySQL如何优化LIMIT 7.2.15. 如何避免表扫描 7.2.16. INSERT语句的速度 7.2.17. UPDATE语句的速度 7.2.18. ...

    Mysql中Join的使用实例详解

    你可以在SELECT, UPDATE 和 DELETE 语句中使用Mysql 的 join 来联合多表查询。 以下我们将演示MySQL LEFT JOIN 和 JOIN 的使用的不同之处。 在命令提示符中使用JOIN 我们在RUNOOB数据库中有两张表 tcount_tbl 和 ...

    mysql5.1中文手册

    MySQL如何简化外部联合 7.2.12. MySQL如何优化ORDER BY 7.2.13. MySQL如何优化GROUP BY 7.2.14. MySQL如何优化LIMIT 7.2.15. 如何避免表扫描 7.2.16. INSERT语句的速度 7.2.17. UPDATE语句的速度...

    mysql官方中文参考手册

    7.2.11. MySQL如何简化外部联合 7.2.12. MySQL如何优化ORDER BY 7.2.13. MySQL如何优化GROUP BY 7.2.14. MySQL如何优化LIMIT 7.2.15. 如何避免表扫描 7.2.16. INSERT语句的速度 7.2.17. UPDATE语句的速度 7.2.18. ...

    mysql网络数据库指南(中文版) part1

    4.2 MySQL 查询优化程序 129 4.2.1 优化程序怎样工作 129 4.2.2 忽略优化 131 4.3 列类型选择与查询效率 132 4.4 有效地装载数据 134 4.5 调度与锁定问题 136 4.6 管理员的优化 137 4.6.1 服务器参数 138 ...

    MySQL5.1参考手册官方简体中文版

    7.2.11. MySQL如何简化外部联合 7.2.12. MySQL如何优化ORDER BY 7.2.13. MySQL如何优化GROUP BY 7.2.14. MySQL如何优化LIMIT 7.2.15. 如何避免表扫描 7.2.16. INSERT语句的速度 7.2.17. UPDATE语句的速度 7.2.18. ...

Global site tag (gtag.js) - Google Analytics