使用UNION ALL、IN、EXISTS或JOIN替代OR可提升MySQL查询性能,核心是让每个子查询独立利用索引,避免全表扫描。

在MySQL查询中遇到
OR
OR
OR
UNION ALL
IN
EXISTS
JOIN
当我们在MySQL中面对一个包含
OR
首先,最直接也最常用的替代方式是UNION ALL
OR
UNION ALL
SELECT
OR
SELECT * FROM users WHERE status = 'active' OR registration_date > '2023-01-01'
status
registration_date
SELECT
UNION ALL
OR
UNION ALL
UNION
UNION
其次,对于针对同一列的多个离散值的查询,
IN
OR
WHERE category_id = 1 OR category_id = 5 OR category_id = 10
WHERE category_id IN (1, 5, 10)
IN
category_id
IN
JOIN
再者,对于一些更复杂的,涉及到子查询或关联表的
OR
EXISTS
JOIN
OR
SELECT * FROM C WHERE C.condition_A = 'X' OR C.id IN (SELECT B.c_id FROM B WHERE B.condition_B = 'Y')
UNION ALL
LEFT JOIN
JOIN
NULL
EXISTS
EXISTS
最后,也是最根本的,有时候
OR
OR
gender = 'male' OR age < 18
OR
AND
在我看来,
OR
OR
AND
想象一下,你有一个
WHERE column1 = value1 OR column2 = value2
column1
column2
OR
OR
此外,当
OR
在我多年的数据库调优经历中,
UNION ALL
OR
场景:
SELECT * FROM products WHERE category_id = 10 OR supplier_id = 5 OR price > 1000;
category_id
supplier_id
price
SELECT
UNION ALL
WHERE status = 'active' OR JSON_EXTRACT(data, '$.flag') = true;
JSON_EXTRACT
data
status = 'active'
status
UNION ALL
OR
ORDER BY
LIMIT
OR
OR
UNION ALL
优势:
SELECT
OR
OR
SELECT
UNION ALL
UNION
OR
SELECT
代码示例:
-- 原始的OR查询 (可能性能不佳) SELECT * FROM orders WHERE customer_id = 123 OR order_date >= '2023-01-01' OR total_amount > 500.00; -- 使用UNION ALL 替代 (SELECT * FROM orders WHERE customer_id = 123) UNION ALL (SELECT * FROM orders WHERE order_date >= '2023-01-01' AND customer_id != 123) -- 注意避免重复,如果不需要去重且重复可接受,则无需AND customer_id != 123 UNION ALL (SELECT * FROM orders WHERE total_amount > 500.00 AND customer_id != 123 AND order_date < '2023-01-01'); -- 同上,避免重复 -- 更通用的UNION ALL,不考虑去重,让应用层处理或后续用DISTINCT (SELECT * FROM orders WHERE customer_id = 123) UNION ALL (SELECT * FROM orders WHERE order_date >= '2023-01-01') UNION ALL (SELECT * FROM orders WHERE total_amount > 500.00);
在实际应用中,如果每个子查询的结果可能存在重复,而你又需要去重,那么在最外层再加一个
DISTINCT
UNION
UNION ALL
当我需要查询一个字段匹配多个离散值时,比如
WHERE status = 'pending' OR status = 'processing' OR status = 'failed'
OR
IN
WHERE status IN ('pending', 'processing', 'failed')IN
优势:
IN
IN
IN
JOIN
OR
status
IN
OR
OR
IN
局限性:
需要注意的是,
IN
OR
WHERE column1 = value1 OR column2 = value2
IN
UNION ALL
代码示例:
-- 原始的OR查询 (针对同一列,冗长且可能效率稍逊)
SELECT order_id, status, customer_id
FROM orders
WHERE status = 'pending' OR status = 'processing' OR status = 'failed';
-- 使用IN操作符替代 (推荐)
SELECT order_id, status, customer_id
FROM orders
WHERE status IN ('pending', 'processing', 'failed');通过
EXPLAIN
IN
当
OR
EXISTS
JOIN
OR
使用EXISTS的场景和优势:
EXISTS
TRUE
EXISTS
IN
JOIN
EXISTS
EXISTS
代码示例 (EXISTS):
-- 原始的OR查询 (可能涉及子查询,效率堪忧) SELECT o.order_id, o.customer_id FROM orders o WHERE o.status = 'cancelled' OR o.order_id IN (SELECT oi.order_id FROM order_items oi WHERE oi.product_id = 789); -- 使用EXISTS替代 SELECT o.order_id, o.customer_id FROM orders o WHERE o.status = 'cancelled' OR EXISTS (SELECT 1 FROM order_items oi WHERE oi.order_id = o.order_id AND oi.product_id = 789);
这里,
EXISTS
orders
order_items
使用JOIN的场景和优势:
JOIN
OR
JOIN
JOIN
JOIN
INNER JOIN
LEFT JOIN
JOIN
代码示例 (JOIN):
-- 原始的OR查询 (可能导致性能问题) SELECT c.customer_id, c.name FROM customers c WHERE c.age < 30 OR c.customer_id IN (SELECT o.customer_id FROM orders o WHERE o.order_date >= CURDATE() - INTERVAL 30 DAY); -- 使用LEFT JOIN + IS NOT NULL 替代 SELECT c.customer_id, c.name FROM customers c LEFT JOIN orders o ON c.customer_id = o.customer_id AND o.order_date >= CURDATE() - INTERVAL 30 DAY WHERE c.age < 30 OR o.order_id IS NOT NULL;
在这个
LEFT JOIN
o.order_id
NULL
o.order_id IS NOT NULL
IN
EXISTS
选择
EXISTS
JOIN
EXISTS
JOIN
JOIN
索引对于任何数据库查询的性能都至关重要,但对于
OR
OR
首先,一个基本的认知是,索引的主要作用是快速定位数据,而不是扫描数据。对于
AND
WHERE col1 = 'A' AND col2 = 'B'
(col1, col2)
然而,当涉及到
OR
WHERE col1 = 'A' OR col2 = 'B'
单列索引的局限性:
col1
col2
col1 = 'A'
col2 = 'B'
col2 = 'B'
OR
col1
col2
col1
col2
OR
复合索引的挑战:
OR
WHERE col1 = 'A' OR col2 = 'B'
(col1, col2)
AND
col2 = 'B'
col1
WHERE (col1 = 'A' AND col2 = 'B') OR (col1 = 'C' AND col2 = 'D')
OR
索引选择性:
OR
OR
以上就是MySQL如何取代OR_MySQL查询中OR条件优化与替代方案教程的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号