我会重新编写查询以组合两个单独的集合,避免WHERE 子句中的OR。
类似这样的:
( SELECT a1.field1
, b1.field2
FROM tableA a1
JOIN tableB b1
ON b1.somefield = a1.somefield
WHERE a1.field1 = 'value1'
)
UNION ALL
( SELECT a2.field1
, b2.field2
FROM tableA a2
JOIN tableB b2
ON b2.somefield = a2.somefield
WHERE b2.field2 = 'value2'
HAVING NOT (a2.field1 <=> 'value1')
)
该查询应该能够有效地利用这些索引,用于 SELECT
... ON tableA (field1,somefield,...)
... ON tableB (somefield,field2,...)
第二次选择
... ON tableA (somefield,field1,...)
... ON tableB (field2,somefield,...)
使用 EXPLAIN 查看执行计划
查看返回集合的另一种方法是三个集合的组合...
- 在 a.field1 和 b.field2 上都匹配的行
- 在 a.field1 上匹配但在 b.field2 上不匹配的行
- 在 b.field2 上匹配但在 a.field1 上不匹配的行
第一个子集是原始查询,将 OR 替换为 AND。
最后两个子集都可以返回
SELECT ...
FROM a
JOIN b
ON ...
WHERE a.field1 = 'value1'
AND NOT ( b.field2 <=> 'value2' )
和
SELECT ...
FROM a
JOIN b
ON ...
WHERE b.field2 = 'value2'
AND NOT ( a.field1 <=> 'value1' )
为每个 SELECT 提供合适的索引,并使用 UNION ALL 集合运算符组合集合。