ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

MySQL 慢查询完整排查

MySQL 慢查询完整排查 1、开启慢查询日志抓慢 SQLslow_query_logON开启慢查询日志long_query_time慢查询阈值单位秒普通业务1~2s金融交易、高并发核心链路500ms(0.5)slow_query_log_file慢日志文件路径log_queries_not_using_indexes记录没有使用索引的 SQL测试环境开启生产谨慎压力大注意long_query_time统计的是SQL 实际执行时间不包含锁等待时间如果 SQL 因为锁等待卡住不会被慢日志捕获。工具mysqldumpslow分析慢日志汇总相同 SQL 的执行次数、平均耗时。2、explain 执行计划重点字段面试高频重点看type、key、rows、ref、Extratype 访问类型优先级从差到优ALLindexrangerefeq_refconst/systemALL全表扫描性能最差必须优化没有可用索引index扫描整个索引树比 all 好但依然大量 IOrange范围查询 in between用到索引范围扫描ref非唯一索引等值匹配命中多行eq_ref唯一索引等值最多匹配一行主键 / 唯一索引关联const常量匹配主键 / 唯一索引直接定位一行生产目标type 尽量达到ref/range禁止大量 SQL 出现ALLkeykey实际真正使用到的索引null 代表没走索引possible_key理论上可以选用的索引不一定真正用到rowsMySQL 预估需要扫描的行数数值越大性能越差是预估值不是真实返回行数。ref索引匹配时使用的列 / 常量显示索引列匹配的是常量还是其他表字段。Extra 额外信息重点坑点Using index✅ 覆盖索引不需要回表性能优秀Using temporary❌ 创建临时表常见于group by、distinct、union消耗内存 / 磁盘性能差Using filesort❌ 文件排序不是磁盘文件是内存排序order by 无法利用索引排序需要额外排序大结果集非常慢Using where存储引擎返回数据后server 层再过滤条件Using join buffer关联查询没用到索引使用连接缓冲区只要出现Using temporary/Using filesort就要重点优化。3、四大层面优化手段① 索引层面最常用给 where、join、order by、group by 字段建立合适索引遵循最左前缀原则联合索引顺序等值条件 范围条件 排序分组字段避免索引失效不要对索引列做函数运算、隐式类型转换like %xxx前缀模糊查询不走 B 树索引or 左右两边字段都要建索引否则索引失效使用覆盖索引减少回表删除冗余、重复、很少使用的索引索引不是越多越好会加重写操作负担② SQL 语句书写层面避免 select *只查需要的字段利于覆盖索引大表禁止select count(*)统计全量limit 大偏移量分页优化延迟关联减少 in 里面大量集合元素大 in 可以改成 join避免order by rand()group by 尽量利用索引避免 Using temporary;filesort拆分大 SQL不要一次性查询超大结果集避免一次性查出几万行以上数据到应用内存少用子查询优先 join避免 not in改用 not exists 或者 left join③ 架构层面读写分离读压力大主写从读分担查询压力分库分表单表数据量千万级别以上水平拆分降低单表扫描行数引入缓存 Redis热点查询直接缓存绕过 MySQL 查询业务层限制查询分页做上限禁止无边界查询④ 数据库设计 配置层面数据库设计合理字段类型尽量小避免大 text/blob 字段大字段单独拆分出去范式适度适当反范式减少多表 join避免大事务事务时间过长会锁等待、MVCC 开销配置参数join_buffer_size、sort_buffer_size、tmp_table_size不要调太大每个连接都会分配内存innodb_buffer_pool_size核心缓存索引和数据页一般设置机器内存 50%~70%慢查询阈值根据业务调整核心链路调小锁相关排查行锁表锁长事务导致锁等待引发慢查询4、补充容易踩坑点explain 只是预估执行计划不一定完全等于真实运行MySQL 优化器会根据数据量选择索引统计信息不准会选错索引可以 analyze table 更新统计信息。慢查询日志抓不到锁等待耗时锁等待问题要看 show engine innodb status、performance_schema。索引优化不是万能写多的业务索引越多插入更新越慢。
返回列表