风离不摆烂学习日志Day21 SQL语句优化笔记
AI-摘要
Tianli GPT
AI初始化中...
介绍自己
生成本文简介
推荐相关文章
前往主页
前往tianli博客
风离不摆烂学习日志Day21 SQL语句优化笔记
排查思路
首先查看Sql语句是否走索引
explain + SQL查询语句
# type结果值从好到坏依次是:
system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
一般情况下 如果是ALl 或者 Index 则表示没走索引 可根据具体情况查看是否 需要创建索引 或者考虑索引失效的几种情况
索引失效的情况
1、使用 != 或者 <> 导致索引失效
2、类型不一致导致索引失效
3、函数导致索引失效
4、运算符导致索引失效
5、模糊搜索导致索引失效
6、NOT IN、NOT EXISTS导致索引失效,
in 是走索引的
7、IS NULL走索引,IS NOT NULL不走索引
Sql语句优化案例1
优化前:
explain
select pg.channel_group_id
from PromotionChannelGroupChannel as pg
where pg.channel_group_id in (select pcg.group_id
from PromotionChannelGroup as pcg
where pcg.parent_group_id = ?
and pcg.company_id = ?
and pcg.state = 1)
or pg.channel_group_id = ?;
在 in 里使用了范围查找 导致走了 index全表扫描 可修改为以下的Sql语句
explain
select pg.channel_group_id
from PromotionChannelGroupChannel as pg
left join PromotionChannelGroup as pcg on pg.channel_group_id = pcg.group_id
where (pcg.parent_group_id = ?
or pg.channel_group_id = ?)
and pcg.company_id = ?
and pcg.state = 1;
Sql语句优化案例2
优化前:
explain SELECT pc.channel_name AS channelName,
pc.channel_id AS channelId,
count(company_account_id) AS pv,
count(DISTINCT pr.company_account_id) AS uv,
pc.channel_key AS utmSource
from PageRecord AS pr
INNER JOIN PromotionChannel AS pc ON pc.company_id = ? AND pr.utm_referer = pc.channel_key AND pc.source = 3
WHERE pr.company_id = ?
AND pc.state = 1
AND pr.data_time between ? AND ?
AND pr.utm_referer != ''
AND pr.state = 1
GROUP BY pc.channel_id
ORDER BY pv DESC, uv DESC;
当无法使用索引的时候,group by 使用两种策略来完成:临时表或者文件排序。 上面的sql语句就是使用了临时表和文件排序
优化后
explain select * from (SELECT pc.channel_name AS channelName,
pc.channel_id AS channelId,
count(company_account_id) AS pv,
count(DISTINCT pr.company_account_id) AS uv,
pc.channel_key AS utmSource
from PageRecord AS pr
INNER JOIN PromotionChannel AS pc ON pc.company_id = 83 AND pr.utm_referer = pc.channel_key AND pc.source = 3
WHERE pr.company_id = 83
AND pc.state = 1
AND pr.data_time between '2023-02-04 00:00:00' AND '2023-02-10 23:59:59'
AND pr.utm_referer != ''
AND pr.state = 1
ORDER BY pv DESC, uv DESC) as temp group by channelId;
解决方案 查询做为整体但是不分组 当做临时表 然后在临时表外根据表中的字段分组
PS 额外的情况
比如重复调用 调用10次这个Sql语句 可能单次的查询时长为 0.2s 但是 多次累加就会很长时间了 解决办法是从代码层面修改逻辑 或者加缓存
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 程序员风离
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果