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