使用UNION替代OR、确保字段有索引、用IN代替多值OR、优化复合索引、避免字段使用函数,可提升MySQL查询性能。
在MySQL中,
OR条件
的使用虽然灵活,但容易导致查询性能下降,尤其是在没有合理索引支持的情况下。优化OR条件的核心在于
避免全表扫描、提升索引利用率、减少执行时间
。以下是几种常见且有效的优化方法。
1. 使用UNION替代OR(适用于不同列或复杂条件)
当OR连接的是不同列的条件时,MySQL可能无法有效使用索引。此时可将查询拆分为多个独立查询,并用
UNION ALL
(无去重)或
UNION
(去重)合并结果。
示例:
原SQL:
若city和age都有独立索引,但组合索引不适用,可改写为:
这样每个子查询都能独立走索引,提升效率。注意避免重复数据时使用UNION,否则加去重会影响性能。
2. 确保OR条件中的字段都有索引
如果OR连接的字段未建立索引,查询会退化为全表扫描。应确保每个OR分支涉及的列都建立了合适的单列或复合索引。
例如:
应为status和user_id分别创建索引,或根据查询频率考虑联合索引。
注意:MySQL 5.7+ 在某些情况下支持
索引合并(Index Merge)
,即同时使用多个索引再取并集,但并非总是生效,依赖优化器判断。
3. 重构查询逻辑,优先使用IN或范围查询
对于同一字段的多个等值条件,用
IN
替代OR更高效且语义清晰。
MySQL(Linux)
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
下载
示例:
应改为:
IN不仅语法简洁,还更容易命中索引,执行计划也更优。
4. 考虑使用复合索引优化多条件OR
当OR条件集中在少数几个字段时,设计合理的复合索引有助于提升性能。但需注意复合索引的顺序和选择性。
例如:
单独为user_id和action建索引可能触发索引合并,但不如针对性优化查询结构来得稳定。
5. 避免函数或表达式包裹字段
在OR条件中对字段使用函数会导致索引失效。
错误示例:
应改写为:
这样可利用create_time的索引进行范围扫描。
基本上就这些关键点。合理使用索引、拆分复杂OR、优先用IN代替等值OR,能显著提升查询效率。实际优化时建议结合
EXPLAIN
分析执行计划,确认是否走索引、有无临时表或文件排序等问题。不复杂但容易忽略细节。
SELECT * FROM users WHERE city = 'Beijing' OR age > 30;SELECT * FROM users WHERE city = 'Beijing'
UNION ALL
SELECT * FROM users WHERE age > 30 AND city != 'Beijing';SELECT * FROM orders WHERE status = 'pending' OR user_id = 100;SELECT * FROM products WHERE category = 'A' OR category = 'B' OR category = 'C';SELECT * FROM products WHERE category IN ('A', 'B', 'C');SELECT * FROM logs WHERE user_id = 1 OR action = 'login';SELECT * FROM users WHERE YEAR(create_time) = 2024 OR MONTH(create_time) = 5;SELECT * FROM users
WHERE create_time >= '2024-01-01' AND create_time < '2025-01-01'
OR (create_time >= '2024-05-01' AND create_time < '2024-06-01');