mysql 优化

本文通过一个具体的案例,讲述了如何优化MySQL查询,从原本执行164条记录耗时6.793秒,优化到0.101秒的过程。关键在于理解IN操作的优化,以及根据内外表大小选择EXISTS或IN。总结了IN优化原则,包括在外表小、内表大时使用IN可能导致效率低下,以及NOT IN不走索引等。建议使用EXPLAIN进行SQL性能分析。

需要查询的表有:

扫描批次表(scan_batch):主键(id),批次编号(batch_no)
扫描信息表(scan_info):主键(id),批次id(batch_id),Jar包id(jar_id)
Jar包信息表(jar_info):主键(id),Jar包其他信息(jar_name,jar_groupId,jar_artifactId,jar_version,jar_type,create_time)

需要查询到的记录是:

某一系统下,某一批次的扫描信息(需要展示的是Jar包的各个信息)。同时可以进行Jar包搜索

原始思路:164条记录 6.793s

SELECT DISTINCT jar_info.jar_name,
            jar_info.jar_groupId,
            jar_info.jar_artifactId,
            jar_info.jar_version,
            jar_info.jar_type,
            jar_info.create_time
    FROM jar_info,scan_batch
    WHERE jar_info.id IN( SELECT jar_id FROM scan_info WHERE app_id=13)
    AND scan_batch.batch_no='20170817165821'
    and jar_info.`jar_artifactId` LIKE CONCAT('%','','%')

自己想当然的理解为先执行括号后边的sql,但事实上是子查询产生一个结果集,其中有多少记录就会和外表进行多少次比较。因此,效率十分低下。

这里写图片描述

初步优化后:164条记录 0.30s

SELECT DISTINCT jar_info.jar_name,
            jar_info.jar_groupId,
            jar_info.jar_artifactId,
            jar_info.jar_version,
            jar_info.jar_type,
            jar_info.create_time
    FROM jar_info,scan_batch
    WHERE jar_info.id IN(  SELECT jar_id FROM(SELECT jar_id FROM scan_info WHERE app_id=13) as tbt)
    AND scan_batch.batch_no='20170817165821'
    and jar_info.`jar_artifactId` LIKE CONCAT('%','','%')

为子查询加临时表之后,执行速度明显提高了,但是在数据库数据量增加的时候,页面响应速度依然非常慢。

这里写图片描述

优化后:164条记录 0.101s

SELECT DISTINCT ji.jar_name,
            ji.jar_groupId,
            ji.jar_artifactId,
            ji.jar_version,
            ji.jar_type,
            ji.create_time
    FROM jar_info ji
        inner join (select si.jar_id from scan_info si 
            inner join scan_batch sb on si.batch_id=sb.id 
            where sb.batch_no='20170817103108' and si.app_id=4) tmp
        on tmp.jar_id = ji.id
        where ji.jar_artifactId like CONCAT('%','','%')

后来请教大佬,换了一种思路,不在用in,将in优化为连接。执行速度提高的不是一点。

这里写图片描述

总结:

1、 in可能被优化为 连接
2、 则子查询表大的用exists,子查询表小的用in
3、 in 在未被优化时,外表小,内表大时(要建临时表并排序 耗时) 效率低
4、 in在数据库数据量非常大的时候效率会很低。
另外:
5、 not in 不走索引的,因此不能用
6、 not exists走索引的。

在进行sql优化时候,很有必要用 explain 对sql语句进行性能分析,以便观察是否用到索引之类。其中各个字段的意思详见:
http://www.jb51.net/article/38357.htm

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值