前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >借助profile优化MySQL查询语句

借助profile优化MySQL查询语句

作者头像
明月AI
发布2022-11-07 13:06:50
1.4K0
发布2022-11-07 13:06:50
举报
文章被收录于专栏:野生AI架构师

问题

上周客户反馈有个功能比较卡,经同事排查是因为一个SQL语句查询比较慢导致的:

代码语言:javascript
复制
SELECT 
        am.article_id,
        am.simhash 
FROM
        `article_mark` AS am
        INNER JOIN `article_distribute_relation` AS adr ON am.article_id = adr.article_id 
WHERE
        am.STATUS = 0 
        AND am.system_type =3
        AND adr.distribute_id IN ( 
            SELECT `id` FROM `article_distribute` 
            WHERE `mark_status` = 0 AND `created_at` >= "2022-08-13" AND `is_deleted` = 0 
        ) 
GROUP BY
        am.article_id

其中adr和am表的记录数大概都是400到500万,而ad表的数据量大概只有三四千。

解决过程

一开始看到只有几百万的数据量就慢查询了,会不会是left join的时候没有用上索引。确认am和adr表的article_id字段,确实都是有索引的,但是他们的字段类型却不太一样,一个是char(24),而另一个是varchar(24)。

都改成char(24),发现没什么效果,看来MySQL也不会那么傻。

explain看看这个语句的执行计划:

从结果看,索引都已经用上了,本来以为rows值(需要扫描的记录数)应该很大,但是看结果也不只有几百,虽然ad表的Extra有“Using index condition; Using where; Using temporar...”,但是这个表的数据量很少,应该不会太影响才对。

这个语句命中的记录行数确实是比较多的(3.6万多),但是返回的两个字段都是业务需要的。一时没了主意,想了一些准备绕过这个问题的解决方案。后来想起phpmyadmin是可以分析sql语句的性能(MySQL profile),分析结果如下:

显然,绝大部分时间都花在了sending data上,眼前一亮,肯定是返回的数据太多或者中间过程的数据量太多,这里还有一个group by,这个可能也是很耗时间的(之前也想过这里,不过当时没有多想,因为group by的字段是有索引的)。

于是去掉group by,用上distinct,分析性能:

从秒级下降到了毫秒级,完美!

在不少情况下,是可以使用distinct来替换group by的,性能会大大的提升。

不妨再回头看一下换成distinct之后的执行计划:

可以看到,和之前是完全一致的。

优化MySQL查询语句,单靠explain是不够的,profile往往是更加有效的方法。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-09-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 野生AI架构师 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档