Optimize MySQL OR Conditions: A UNION Rewrite Guide


In complex join query scenarios, OR logic within JOIN conditions often becomes a performance bottleneck. When the ON clause of a LEFT JOIN contains multi-column OR conditions, the MySQL optimizer often cannot effectively utilize indexes, leading to full table scans or the “Range checked for each record” strategy, causing a sharp performance decline. This solution is based on an actual business scenario, using 20,000-level test data, comparing execution plans, and analyzing cost metrics to validate the significant effectiveness of the UNION rewrite technique for optimizing OR conditions. Test results show that by splitting the OR condition into independent queries and merging them with UNION, performance improved by up to 96.02%, execution time dropped from 19.62 seconds to 0.78 seconds, and execution cost was reduced by 99.88%. This article will deeply analyze the optimization principles, applicable boundaries, and implementation key points, providing developers with actionable performance optimization guidance.
| |
| |
| |
We attempted to rewrite using SQLFlash.

The rewritten SQL is as follows:
| |
View detailed report:https://sqlflash.ai/app/sqlResult?shareid=1707274c-377c-4c44-afd1-49a6062dee8b
According to the analysis by SQLFlash, the OR condition (rvc.rs_product_code=rpvb.code OR rvc.config_combination_no=rpvb.code) in the original SQL caused the MySQL optimizer to be unable to effectively use indexes, adopting the “Range checked for each record” strategy. Each record had to be evaluated for index usage, resulting in extensive full table scans during actual execution. After rewriting, the OR condition is split into two independent queries using UNION, allowing each query to stably use the idx_code index for ref access. The first query handles cases where rs_product_code matches, and the second query handles cases where config_combination_no matches, with NOT EXISTS ensuring no duplicate records are produced. The query cost dropped from 4.85 million to just over 5,000, a reduction of 99.88%, demonstrating a significant performance improvement.
| |
| |
| Item | Original Query | Optimized Query |
|---|---|---|
| SQL Structure | LEFT JOIN + OR condition | UNION + Independent JOIN |
| Execution Time | 19.6223s | 0.7804s |
| Performance Improvement | - | 96.02% |
| Time Saved | - | 18.84s |
| Query Cost | 4,857,670.32 | 5,592.74 |
| Cost Reduction | - | 99.88% |
| rpvb Access Type | ALL (Full Table Scan) | ref (Index Seek) |
| Index Usage | Range checked | Stable use of idx_code |
| Estimated Rows Processed | 48,509,450 | ~10,000 |
| Extra Information | Range checked for each record | Using index (subquery) |
| Temporary Table | Possible | UNION temp table (Controllable) |
The root cause of the performance issue is: When OR appears in the ON clause of a JOIN, MySQL cannot use multiple indexes simultaneously, ultimately degenerating into:
Range checked for each record)By splitting the OR into two subqueries and merging them with UNION:
In join queries, if the ON clause of a LEFT JOIN contains multiple OR conditions, and each condition corresponds to a different index, priority should be given to splitting the query into multiple independent statements and merging them with UNION. This approach ensures that each subquery stably uses indexes, significantly reducing scan volume and execution cost. When developing, just remember: If OR appears in a JOIN, it’s highly likely that UNION is needed to rescue performance.
SQLFlash is your AI-powered SQL Optimization Partner.
Based on AI models, we accurately identify SQL performance bottlenecks and optimize query performance, freeing you from the cumbersome SQL tuning process so you can fully focus on developing and implementing business logic.
Join us and experience the power of SQLFlash today!.