慢查询优化核心是定位瓶颈、减少数据扫描、提升执行效率,需从执行计划、索引设计、SQL写法和服务器配置四层面入手:看懂EXPLAIN(关注type/key/rows/Extra)、合理建索引(覆盖索引、避免函数操作)、重写SQL(EXISTS替代IN、游标分页、限制JOIN数)、配合参数调优(慢日志、缓冲区、统计信息更新)。

慢查询优化核心是定位瓶颈、减少数据扫描、提升执行效率。重点看执行计划、索引设计、SQL写法和服务器配置四个层面。
看懂EXPLAIN执行计划
用EXPLAIN分析SQL实际执行路径,重点关注:
- type:尽量达到range、ref或const,避免ALL(全表扫描)和index(全索引扫描)
- key:是否命中有效索引;NULL表示没走索引
- rows:预估扫描行数,远大于结果集行数说明索引选择不佳或条件过滤性差
- Extra:出现Using filesort或Using temporary需警惕,通常意味着排序/分组未走索引
合理设计和使用索引
索引不是越多越好,要匹配查询模式:
本文档主要讲述的是lucene索引优化;这篇文章主要介绍了如何提高Lucene的索引速度。介绍的大部分思路都是很容易尝试的,当然另外一部分可能会加大你程序的复杂度。所以请确认索引速度确实很慢,而且很慢的原因确实是因为Lucene自身而造成的;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
- WHERE条件中的字段优先建索引,按选择性高→低顺序组合(如
status, create_time比create_time, status更易命中) - 覆盖索引能避免回表:SELECT字段全部包含在索引中,例如查
id, name, age,可建联合索引(name, age, id) - 避免对索引字段做函数操作或隐式类型转换,如
WHERE YEAR(create_time) = 2024或WHERE mobile = 13800138000(mobile是字符串)会导致索引失效 - 定期用
SHOW INDEX FROM table_name检查冗余索引,删除长期未被使用的索引
重写低效SQL语句
很多慢查源于写法不当,而非数据量大:
- 用
EXISTS替代IN子查询(尤其子查询结果集大时),避免生成临时结果集 - 分页深翻慎用
LIMIT 10000, 20,改用“游标分页”:记录上一页最大ID,用WHERE id > xxx LIMIT 20 - 避免
SELECT *,只取必要字段;大文本字段(如TEXT)单独查询,不与主表JOIN一起加载 - JOIN表数控制在3张以内,确保每张JOIN表都有关联字段的索引,且驱动表(左表)结果集尽量小
配合数据库参数与监控调优
单靠SQL和索引不够,还需系统级配合:
- 开启慢查询日志:
slow_query_log = ON,设置合理阈值(如long_query_time = 1),用mysqldumpslow或pt-query-digest分析热点SQL - 调整缓冲区:适当增大
sort_buffer_size、join_buffer_size(按需设置,避免过大占用内存) - 检查表统计信息是否过期,执行
ANALYZE TABLE table_name让优化器获得准确行数估算 - 对高频慢查考虑读写分离或冷热分离,大表及时归档历史数据









