系列导读:本篇将深入讲解数据库性能优化的核心方法与实战技巧。
文章目录
-
- [一、SQL 优化](#一、SQL 优化)
-
- [1.1 慢查询分析](#1.1 慢查询分析)
- [1.2 EXPLAIN 解读](#1.2 EXPLAIN 解读)
- [1.3 优化原则](#1.3 优化原则)
- 二、索引优化
-
- [2.1 索引类型](#2.1 索引类型)
- [2.2 索引设计原则](#2.2 索引设计原则)
- [2.3 组合索引示例](#2.3 组合索引示例)
- 三、架构优化
-
- [3.1 读写分离](#3.1 读写分离)
- [3.2 分库分表](#3.2 分库分表)
- [3.3 缓存策略](#3.3 缓存策略)
- 四、连接池优化
-
- [4.1 HikariCP 配置](#4.1 HikariCP 配置)
- [4.2 连接池监控](#4.2 连接池监控)
- 总结
一、SQL 优化
1.1 慢查询分析
sql
-- 开启慢查询日志
SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 1;
-- 分析慢查询
EXPLAIN SELECT * FROM orders WHERE user_id = 100;
1.2 EXPLAIN 解读
| 字段 | 说明 |
|---|---|
| type | 访问类型(ALL/index/range/ref/const) |
| key | 使用的索引 |
| rows | 扫描行数 |
| Extra | 额外信息 |
1.3 优化原则
sql
-- 避免 SELECT *
SELECT id, name FROM users WHERE id = 1;
-- 避免函数操作
-- 差
SELECT * FROM orders WHERE DATE(create_time) = '2024-01-01';
-- 好
SELECT * FROM orders WHERE create_time >= '2024-01-01' AND create_time < '2024-01-02';
-- 避免 OR
-- 差
SELECT * FROM users WHERE name = '张三' OR age = 20;
-- 好
SELECT * FROM users WHERE name = '张三'
UNION
SELECT * FROM users WHERE age = 20;
-- 分页优化
-- 差
SELECT * FROM orders LIMIT 1000000, 10;
-- 好
SELECT * FROM orders WHERE id > 1000000 LIMIT 10;
二、索引优化
2.1 索引类型
| 类型 | 说明 |
|---|---|
| 主键索引 | 唯一、非空 |
| 唯一索引 | 唯一 |
| 普通索引 | 加速查询 |
| 组合索引 | 多列索引 |
| 全文索引 | 文本搜索 |
2.2 索引设计原则
1. 选择区分度高的列
2. 遵循最左前缀原则
3. 覆盖索引减少回表
4. 控制索引数量
5. 避免冗余索引
2.3 组合索引示例
sql
-- 组合索引
CREATE INDEX idx_user_status_time ON orders(user_id, status, create_time);
-- 命中索引
SELECT * FROM orders WHERE user_id = 1;
SELECT * FROM orders WHERE user_id = 1 AND status = 1;
SELECT * FROM orders WHERE user_id = 1 AND status = 1 AND create_time > '2024-01-01';
-- 不命中索引
SELECT * FROM orders WHERE status = 1;
SELECT * FROM orders WHERE create_time > '2024-01-01';
三、架构优化
3.1 读写分离
yaml
# ShardingSphere 配置
spring:
shardingsphere:
datasource:
names: master,slave
master:
type: com.zaxxer.hikari.HikariDataSource
jdbc-url: jdbc:mysql://master:3306/mydb
slave:
type: com.zaxxer.hikari.HikariDataSource
jdbc-url: jdbc:mysql://slave:3306/mydb
rules:
readwrite-splitting:
data-sources:
myds:
write-data-source-name: master
read-data-source-names: slave
3.2 分库分表
yaml
# 分片配置
spring:
shardingsphere:
rules:
sharding:
tables:
t_order:
actual-data-nodes: ds${0..1}.t_order_${0..1}
table-strategy:
standard:
sharding-column: order_id
sharding-algorithm-name: order-inline
3.3 缓存策略
java
// 缓存穿透防护
public User getUser(Long id) {
String key = "user:" + id;
User user = redisTemplate.opsForValue().get(key);
if (user != null) {
return user;
}
// 防止缓存穿透
if (redisTemplate.hasKey("null:" + id)) {
return null;
}
user = userMapper.selectById(id);
if (user != null) {
redisTemplate.opsForValue().set(key, user, 1, TimeUnit.HOURS);
} else {
// 空值缓存
redisTemplate.opsForValue().set("null:" + id, "", 5, TimeUnit.MINUTES);
}
return user;
}
四、连接池优化
4.1 HikariCP 配置
yaml
spring:
datasource:
hikari:
minimum-idle: 10
maximum-pool-size: 50
idle-timeout: 600000
max-lifetime: 1800000
connection-timeout: 30000
pool-name: OrderHikariPool
4.2 连接池监控
java
// 获取连接池状态
HikariDataSource dataSource = (HikariDataSource) applicationContext.getBean(DataSource.class);
HikariPoolMXBean pool = dataSource.getHikariPoolMXBean();
log.info("活跃连接: {}", pool.getActiveConnections());
log.info("空闲连接: {}", pool.getIdleConnections());
log.info("等待线程: {}", pool.getThreadsAwaitingConnection());
总结
✅ SQL 优化 :慢查询、EXPLAIN、优化原则
✅ 索引优化 :类型、设计原则、组合索引
✅ 架构优化 :读写分离、分库分表、缓存
✅ 连接池优化:HikariCP 配置、监控
作者 :刘~浪地球
更新时间:2026-04-17