sql查询优化的核心是减少i/o与cpu开销,关键在于高效执行计划、合理索引和数据访问路径;需遵循最左前缀原则、避免索引列函数操作、精简查询字段、善用explain分析,杜绝or滥用、深子查询等反模式。

SQL查询优化的核心是减少数据库的I/O开销和CPU计算压力,让查询在更短时间内返回准确结果。关键不在于写得多“炫”,而在于让执行计划更高效、索引更到位、数据访问路径更合理。
善用索引,但别迷信索引
索引能极大加速WHERE、JOIN、ORDER BY和GROUP BY等操作,但前提是查询条件能有效命中索引列,并遵循最左前缀原则。例如,对(a, b, c)建联合索引,WHERE a = ? AND b > ? 可用索引;而 WHERE b = ? 或 WHERE c = ? 则无法使用该索引。
- 避免在索引列上做函数操作,如 WHERE YEAR(create_time) = 2024 会失效索引,应改写为 WHERE create_time BETWEEN '2024-01-01' AND '2024-12-31'
- 区分度低的字段(如性别、状态码)单独建索引意义不大,可考虑作为联合索引的后置列
- 定期检查冗余索引和未被使用的索引,用 SHOW INDEX 和慢日志分析工具辅助判断
精简查询范围,减少数据搬运
数据库最耗时的操作之一是把大量数据从磁盘读到内存,再传给应用。越早过滤、越少扫描,性能越好。
MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除 了几乎所有的 JDBC 代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML 或注解用于配置和原始映射,将接口和 Java 的 POJOs(Plan Old Java Objects,普通的 Java 对象)映射成数据库中的记录。有需要的朋友可以下载看看
- 只查需要的字段,避免 SELECT *,尤其表中含TEXT/BLOB大字段时
- 用 LIMIT 配合分页逻辑(注意深分页问题),必要时用游标分页替代 OFFSET
- 对大数据量表,优先在WHERE中加入高选择性条件(如主键、唯一业务ID),再叠加其他筛选
- 关联查询时,确保JOIN字段类型一致、均有索引,小表驱动大表(MySQL中,驱动表应尽量小)
理解执行计划,不靠猜测调优
EXPLAIN 是SQL优化的起点。重点关注 type(访问类型)、key(实际索引)、rows(预估扫描行数)、Extra(额外操作)等字段。
- type = ALL 表示全表扫描,需优先排查是否缺索引或索引失效
- Extra = Using filesort / Using temporary 暗示排序或分组未走索引,可考虑添加覆盖索引
- 对比实际执行时间与EXPLAIN预估行数差异过大,可能统计信息过期,可运行 ANALYZE TABLE 更新
避免常见反模式
有些写法看似简洁,实则严重拖慢性能,且不易察觉。
- 在WHERE中使用 OR 连接不同字段条件(如 a=1 OR b=2),常导致索引失效,可拆成UNION ALL(注意去重成本)
- 子查询嵌套过深,尤其相关子查询,易引发N+1问题;优先考虑JOIN或改写为派生表
- 在应用层拼接大量IN列表(如 IN (1,2,...,5000)),不仅SQL长、解析慢,还可能触发执行计划缓存失效;可分批次或用临时表替代
- 忽略字符集/排序规则不一致导致的隐式转换,例如 utf8mb4 与 utf8 字段JOIN,可能跳过索引









