一、SQL 执行慢排查与优化方案
1. SQL 执行慢排查步骤
- 查看执行计划:通过
EXPLAIN
分析 SQL 执行计划,重点关注type
(访问类型,如ALL
表示全表扫描,性能差)、key
(是否使用索引)、rows
(预估扫描行数)。 - 检查索引使用情况:确认是否走索引,是否存在索引失效(见下文 “索引失效原因”)。
- 分析锁等待:通过
SHOW PROCESSLIST
查看是否有锁阻塞(如行锁、表锁),INFORMATION_SCHEMA.INNODB_LOCKS
查看锁详情。 - 统计信息更新:表数据变化大时,统计信息过时可能导致执行计划不准,执行
ANALYZE TABLE
更新统计信息。 - 日志定位:开启慢查询日志(
slow_query_log=1
),设置long_query_time
阈值(如 2 秒),记录慢 SQL 进行分析。
2. SQL 优化方案
- 优化索引:为过滤条件、排序字段、关联字段建立合适索引(见下文 “索引设计原则”)。
- 改写 SQL:
- 避免
SELECT *
,只查询必要字段。 - 拆分复杂
JOIN
,避免多表关联时扫描大表。 - 用
UNION ALL
替代OR
(索引友好),用EXISTS
替代IN
(大数据量时)。
- 分页优化:避免
LIMIT 100000, 10
(扫描大量无用数据),可通过主键定位:WHERE id > 100000 LIMIT 10
。 - 减少锁冲突:避免长事务,批量操作拆分小批次执行。
二、索引设计原则
- 字段值重复率高(如
gender
,区分度低)。 - 表数据量小(全表扫描比索引快)。
- 频繁更新的字段(索引维护成本高)。
三、分表分库方案
1. 分表(单库内拆分)
- 水平分表(按行拆分):
- 范围分表:按时间(如
order_2023
、order_2024
)、ID 范围(如user_0
到user_9
按 ID 模 10)。 - 哈希分表:ID 哈希后取模(如
user_{id%10}
),适合均匀分布场景。
- 垂直分表(按列拆分):将大表按字段关联性拆分(如
user
拆分为user_base
(基本信息)和user_extra
(扩展信息))。
2. 分库(多库拆分)
- 水平分库:同水平分表逻辑,将数据分散到不同库(如按用户 ID 哈希分库,再在库内分表)。
- 垂直分库:按业务模块拆分(如订单库、用户库、商品库),降低单库压力。
3. 中间件选择
- 分库分表中间件:ShardingSphere-JDBC(轻量级,客户端模式)、MyCat(代理模式)。
- 路由策略:通过中间件配置分片规则(如哈希、范围),透明化分库分表逻辑。
四、哈希表扩容
- 非并发场景:直接扩容,期间暂停读写。
- 并发场景(如 Java
ConcurrentHashMap
):采用分段锁,逐段扩容,不阻塞读写。
五、导致索引失效的原因
六、Spring Cloud 常用组件及作用
七、MySQL 与 Oracle 使用区别
维度 | MySQL | Oracle | ||
事务隔离级别 | 默认 | 默认 | ||
分页语法 |
|
| ||
自增主键 | 支持 | 需通过序列( | ||
索引类型 | 主要支持 B + 树,部分引擎支持哈希索引 | 支持 B + 树、 bitmap、函数索引等 | ||
存储引擎 | 多引擎(InnoDB、MyISAM 等),InnoDB 为主 | 单一引擎(类似 InnoDB,支持事务) | ||
函数差异 | 字符串函数: | 字符串函数:` |
| |
锁机制 | InnoDB 支持行锁、表锁 | 支持行锁、表锁、间隙锁,锁机制更复杂 | ||
适用场景 | 互联网、中小规模应用,开源免费 | 大型企业级应用,收费,稳定性强 |
八、开发常用注解(Spring + MyBatis)
Spring 注解
@Controller
/@Service
/@Repository
/@Component
:标识 Spring 组件,纳入 IOC 容器。@RestController
:组合@Controller
+@ResponseBody
,返回 JSON。
@Autowired
:自动注入依赖(按类型,配合@Qualifier
按名称)。@Resource
:JDK 注解,按名称注入。
MyBatis 注解
九、Redis 持久化机制
- 原理:在指定时间间隔内,将内存中的数据集快照写入磁盘(二进制文件,如
dump.rdb
)。 - 触发方式:手动执行
SAVE
(阻塞)/BGSAVE
(后台异步),或配置save <seconds> <changes>
自动触发。 - 优点:文件小,恢复快;缺点:可能丢失最后一次快照后的所有数据。
- 原理:记录所有写操作命令到日志文件(文本格式),重启时重新执行命令恢复数据。
- 配置:
appendonly yes
开启,appendfsync
控制刷盘策略(always
实时刷盘,everysec
每秒刷盘,no
由 OS 控制)。 - 优点:数据安全性高(最多丢失 1 秒数据);缺点:文件大,恢复慢。
十、接口请求很慢排查步骤
- 检查网络耗时(浏览器 F12 的 Network 面板,看
TTFB
(首字节时间)和Content Download
耗时)。 - 确认是否前端渲染慢(如大量 DOM 操作)。
- 接口耗时统计:在接口入口 / 出口打印时间戳,计算总耗时。
- 分阶段定位:
- 数据库操作:通过日志记录 SQL 执行时间,排查慢查询(见 SQL 慢排查)。
- 外部服务调用:检查调用第三方接口的响应时间(如 HTTP、RPC)。
- 代码逻辑:是否有复杂计算、死循环、线程阻塞(用
jstack
分析线程栈)。
- 资源监控:
- 服务器:CPU、内存、磁盘 IO、网络(
top
、free
、iostat
命令)。 - JVM:GC 频率、堆内存使用(
jstat
、jmap
),是否有频繁 Full GC 导致卡顿。
- 分布式追踪:若用 Spring Cloud,通过 Sleuth+Zipkin 查看跨服务调用链路,定位哪个服务耗时最长。
- 缓存(Redis):检查是否缓存失效导致大量穿透到 DB,或 Redis 响应慢(
INFO
命令看latency
)。 - 消息队列:检查是否队列积压,消费者处理慢导致接口等待。
- 加缓存(Redis)减轻 DB 压力。
- 异步化处理非核心逻辑(如消息通知)。
- 优化 SQL 和索引,减少 DB 耗时。
- 扩容服务器或数据库(垂直 / 水平扩容)。