在"或"时优化MySQL查询用来

时间:2014-03-12 11:42:47

标签: mysql

这两个表包含超过1m的记录。

此查询需要15秒才能运行并返回1条记录(正确):

    select orders.*
        from orders
    left join orders_details on orders.orderID=orders_details.orderID
        where 
orders_details.trackingRef='GYD41624' 
or orders.orderID = (
select distinct  orderID from orders_rebookings
 where trackingRef='GYD41624'
)   
    group by orders.orderID

然而,如果我分别运行每个where条件的查询,那么每个条件都很快:

这需要0.0015秒(找到1个匹配项):

select orders.*
    from orders
left join orders_details on orders.orderID=orders_details.orderID
    where orders.orderID = (select distinct orderID from orders_rebookings where trackingRef='GYD41624')    
group by orders.orderID

这几乎没有时间,发现没有匹配(这是正确的):

select orders.*
    from orders
left join orders_details on orders.orderID=orders_details.orderID
    where orders_details.trackingRef='GYD41624'     
group by orders.orderID

因此,如果我有两个非常快速的查询,我怎样才能使第一个包含"或"几乎一样快?

1 个答案:

答案 0 :(得分:0)

您可以使用unionunion all组合它们:

select o.*
from orders o left join
    orders_details od
    on o.orderID = od.orderID
where o.orderID = (select distinct orderID from orders_rebookings where trackingRef = 'GYD41624')    
group by o.orderID
union
select o.*
from orders o left join
     orders_details od
     on o.orderID = od.orderID
where od.trackingRef = 'GYD41624'     
group by o.orderID;

union的效率稍差,因为它会删除重复项。

您的查询也很危险,因为它有= (select . . .)。如果子查询返回多行,则会出现错误。

我想知道这种形式是否表现更好:

select o.*
from orders o
where exists (select 1 from orders_details where o.orderID = od.orderID and od.trackingRef = 'GYD41624') or
      exists (select 1 from orders_rebookings orr where o.orderID = orr.orderID and orr.trackingRef = 'GYD41624')       

您需要适当的索引(orders_details(orderId, TrackingRef)orders_rebookings(orderId, trackingRef))。