
Spring Boot 项目中慢 SQL 优化是一个重要的性能优化环节。以下是一些常用的慢 SQL 优化方案,涵盖了从 SQL 语句本身到数据库配置、应用层优化的多个方面:
1. 识别慢 SQL:
慢查询日志 (Slow Query Log):
MySQL、PostgreSQL 等数据库都提供了慢查询日志功能。
开启慢查询日志,设置阈值(例如,超过 1 秒的查询被认为是慢查询)。
分析慢查询日志,找出执行时间较长的 SQL 语句。
MySQL 示例:
-- 开启慢查询日志
SET GLOBAL slow_query_log = 'ON';
-- 设置慢查询阈值 (单位:秒)
SET GLOBAL long_query_time = 1;
-- 查看慢查询日志文件路径
SHOW VARIABLES LIKE 'slow_query_log_file';
数据库监控工具:
应用性能监控 (APM) 工具:
Spring Boot Actuator (Metrics):
/actuator/metrics
端点,可以暴露应用程序的各种指标,包括数据库连接池的使用情况、SQL 执行时间等(需要集成 Micrometer 和相应的数据库驱动)。Druid (或其他数据库连接池) 监控:
wall
防火墙 (可选).自定义拦截器/AOP:
2. SQL 语句优化:
使用
EXPLAIN
分析查询计划:
EXPLAIN
关键字,可以查看 MySQL 如何执行该查询。EXPLAIN
的输出,关注以下几点:
type
: 连接类型,从好到差依次为:
system
、
const
、
eq_ref
、
ref
、
range
、
index
、
ALL
。尽量避免
ALL
(全表扫描)。possible_keys
: 可能使用的索引。key
: 实际使用的索引。rows
: 预计扫描的行数。Extra
: 额外信息,例如
Using filesort
(需要排序)、
Using temporary
(需要使用临时表) 等。优化索引:
WHERE
子句中的列JOIN
子句中的连接列ORDER BY
子句中的列GROUP BY
子句中的列优化查询语句:
SELECT *
:
只查询需要的列,减少数据传输量。WHERE
子句中使用
!=
或
<>
:
这会导致索引失效。WHERE
子句中对列进行
NULL
值判断:
应该使用
IS NULL
或
IS NOT NULL
。WHERE
子句中使用
OR
连接非索引列:
可以考虑使用
UNION
或
UNION ALL
。JOIN
代替子查询:
子查询可能会导致性能问题。JOIN
操作:
JOIN
的数量。ORDER BY
和
GROUP BY
操作:
LIMIT
分页:
避免一次性查询大量数据。LIKE '%keyword%'
:
这会导致索引失效。如果需要模糊查询,可以考虑使用全文索引。其他优化:
3. 数据库配置优化:
调整缓冲区大小:
innodb_buffer_pool_size
(InnoDB 存储引擎): 缓存表数据和索引数据。key_buffer_size
(MyISAM 存储引擎): 缓存索引数据。sort_buffer_size
: 排序缓冲区大小。join_buffer_size
: 连接缓冲区大小。read_buffer_size
: 读缓冲区大小。read_rnd_buffer_size
: 随机读缓冲区大小。调整连接数:
max_connections
: 最大连接数。max_user_connections
: 每个用户的最大连接数。开启查询缓存 (Query Cache): (MySQL 8.0 已移除)
其他参数:
innodb_log_file_size
: InnoDB 日志文件大小。innodb_flush_log_at_trx_commit
: InnoDB 日志刷新策略。sync_binlog
: 二进制日志刷新策略。硬件优化:
4. 应用层优化:
ConcurrentHashMap
、Guava Cache、Ehcache 等在应用内缓存数据。Cache-Control
、
ETag
、
Last-Modified
)缓存静态资源。@Async
、
CompletableFuture
、消息队列)处理耗时的操作,避免阻塞主线程。5. 其他:
总结:
慢 SQL 优化是一个综合性的工作,需要从多个方面入手,包括:
EXPLAIN
分析查询计划,优化索引,优化查询语句。