一、慢查询怎么定位
开慢查询日志:slow_query_log=1、long_query_time=1,结合 mysqldumpslow 或 pt-query-digest 找最耗时的 SQL,再用 EXPLAIN 分析。
二、避免 SELECT *
- 只取需要的列,利于覆盖索引避免回表;
- 减少网络与内存开销,尤其大字段(text/blob);
- 防止表结构变更带来的隐性影响。
三、深分页优化
LIMIT 100000, 20 要扫描 10 万行再丢弃,极慢。改为”游标分页”:
-- 传统深分页(慢)
SELECT * FROM orders ORDER BY id DESC LIMIT 100000, 20;
-- 游标分页(快):记住上一页最大 id
SELECT * FROM orders WHERE id < :last_id
ORDER BY id DESC LIMIT 20;
四、JOIN 优化
| 要点 | 做法 |
|---|---|
| 小表驱动大表 | 让被驱动表的关联列有索引 |
| 关联列建索引 | ON 条件列必须有索引,否则笛卡尔积 |
| 子查询改 JOIN | IN 子查询在某些版本很慢,改成 JOIN |
五、其他高频优化
- 批量插入:
INSERT INTO t VALUES (...),(...)一次多行,比逐条快很多; - COUNT 优化:
COUNT(*)不慢(InnoDB 已优化),别用COUNT(列)还多一层非空判断; - 避免 ORDER BY 非索引列:否则 filesort;
- 不要在 WHERE 里用 != / NOT IN 滥用,易放弃索引。
六、写操作优化
- 合理事务粒度,别长事务占锁;
- 大批量改数据分批提交,避免 undo 暴涨与锁表;
- 热点行更新用乐观锁或合并计数,减少行锁竞争。
SQL 优化的顺序是:先找慢 SQL(量化)→ EXPLAIN 看执行计划 → 改写法或加索引 → 再验证。别凭感觉建索引。