MySQL慢查询优化&缩容实践
枚举字段的默认值条件导致不走索引
create table test_tb(
`uid` bigint unsigned not null,
`status` enum('A','B','C') NOT NULL DEFAULT 'A'
KEY `idx_on_auid` (`uid`,`status`)
)
// 当查询条件为status为A时会全表扫描
select * from test_tb where uid=111 and status='A'
// status条件为非默认值时会走索引
select * from test_tb where uid=111 and status='B'
// 主要是优化器估算误差的原因导致,从information_schema.tables 查询test_tb表中只有52条数据,实际用select count(*) 查询有几万条数据。优化器的估算误差导致没走预期索引,如果该表不大,则可以跟业务沟通确认是否可以放缓存。
索引调整
在一个数据量较大的订单表中,发现某些查询因为缺少合适的索引而变慢。添加了必要的索引后,查询效率明显提升。
查询条件调整
- 在一个sql中需要根据时间条件查询,但是等号左边的字段使用了函数操作(将时间戳转换成了年月日),导致索引失效进行了全表扫描。解决:将等号右边的条件反向转换成表里的字段类型。
- 一个统计报表的查询非常慢,原因是查询需要处理大量的数据。通过优化查询条件,只获取必要的数据,减少了数据的处理量,从而加快了查询速度。
分区处理
一个表中有大量的删除操作,后续将其按指定字段分区,定时drop分区
频繁调用的sql
与业务人员沟通,将其放入缓存
消除排序
将排序字段添加到索引上。(并不是所有都可以这样,要看具体的sql中排序字段所处的位置)
优化器没使用指定索引
通过explain analyze 去看一条语句执行时的信息统计,比较cost与actual time,再使用explain analyze force index去看使用指定索引的开销,确认是否没走合适的索引。
如果没走建立的指定索引,这是最难搞的,线上不允许使用optimize table,业务那边也不愿意使用force index。一般这种表的分析主要看
- 表的大小
- sql的频率
如果表比较小,则可以将其放到缓存中。或者等维护的时候清理表的碎片,但是需要提前克隆实例,测量操作时间。
或者等维护的时候删除原有的索引,再新创建一个索引,但是要确保删除的索引不会影响其他sql语句。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)