文章目录
一、为什么优化比写代码更重要?🚀
(真实故事预警)上周帮朋友公司救火,一个原本3秒响应的接口突然飙到15秒!最后发现是漏了一个联合索引!老铁们注意啦,优化才是后端开发的真功夫!!!
二、索引优化的三大黄金法则(必考知识点)
2.1 索引不是越多越好!🙅♂️
我的踩坑经历:去年给用户表加了8个索引,结果写入速度直接腰斩!血泪教训啊!
- 正确姿势:
划重点:优先覆盖高频查询字段组合-- 创建联合索引的正确姿势 ALTER TABLE orders ADD INDEX idx_user_time (user_id, create_time);
2.2 索引失效的5种作死操作(面试高频)
-
在WHERE中对字段做计算:
SELECT * FROM users WHERE YEAR(create_time) = 2023; -- 索引失效!
优化方案:
SELECT * FROM users WHERE create_time BETWEEN '2023-01-01' AND '2023-12-31';
-
使用
OR
连接不同字段(超级重要)SELECT * FROM orders WHERE status = 1 OR total_price > 100; -- 全表扫描警告!
2.3 最左前缀原则实战
(面试官最爱)假设有索引(A,B,C),以下查询能用索引吗?
SELECT * FROM table WHERE B=2 AND C=3; -- ❌
SELECT * FROM table WHERE A=1 AND C=3; -- ✅(只用到A)
三、SQL语句优化的骚操作💡
3.1 EXPLAIN命令解密
看这个执行计划,你能发现什么问题?
EXPLAIN SELECT * FROM products WHERE category = '电子' ORDER BY price DESC;
关键字段解读:
- type:ALL → 全表扫描警告!
- Extra:Using filesort → 排序没走索引
3.2 分页查询优化大法
常见错误写法:
SELECT * FROM logs
ORDER BY create_time DESC
LIMIT 1000000, 10; -- 慢到怀疑人生!
优化方案(亲测提速20倍):
SELECT * FROM logs
WHERE create_time < '2023-06-01'
ORDER BY create_time DESC
LIMIT 10;
四、表结构设计的艺术🎨
4.1 字段类型选择技巧
(真实案例)把手机号存成VARCHAR(20) vs BIGINT:
- VARCHAR:浪费存储空间
- BIGINT:节省30%空间,查询更快
4.2 大字段分离策略
用户表设计对比:
-- 错误示范
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(50),
profile TEXT -- 包含大段个人简介
);
-- 正确姿势
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(50)
);
CREATE TABLE user_profiles (
user_id INT PRIMARY KEY,
profile TEXT
);
五、参数调优的隐藏Buff⚙️
5.1 InnoDB缓冲池设置
查看当前配置:
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
调优建议:设置为物理内存的60-80%
5.2 连接数控制
避免出现Too many connections错误:
-- 动态调整(重启失效)
SET GLOBAL max_connections = 500;
六、慢查询日志实战分析🔍
配置慢查询日志:
[mysqld]
slow_query_log = 1
long_query_time = 1
slow_query_log_file = /var/log/mysql/slow.log
分析工具推荐:
mysqldumpslow -s t /var/log/mysql/slow.log
七、分库分表的进阶玩法🚀
7.1 水平拆分实战
原始订单表:
CREATE TABLE orders (
id BIGINT PRIMARY KEY,
user_id INT,
amount DECIMAL(10,2)
);
-- 拆分成4个分表
CREATE TABLE orders_0 (...);
CREATE TABLE orders_1 (...);
CREATE TABLE orders_2 (...);
CREATE TABLE orders_3 (...);
7.2 分片键选择策略
常见方案:
- 用户ID取模
- 时间范围分片
- 地理位置分片
八、面试必刷的10道压轴题🔥
- 为什么有时候索引更快却不用?(成本计算问题)
- 如何优化
COUNT(*)
查询?(答案:用近似值或单独计数表) - 什么情况下会出现死锁?(索引顺序不一致导致)
- 如何设计一个支持模糊查询的索引?(答案:前缀索引)
- 主键用自增ID还是UUID?(场景分析题)
最后说句大实话💬
优化没有银弹!去年我接手的一个电商系统,光是调整join_buffer_size
参数就让查询速度提升了3倍。建议大家多关注EXPLAIN
的结果,定期分析慢查询日志,记住:最适合业务场景的优化才是最好的!