2015-05-29 51 views
2

我想知道你是否能幫助我,我目前有一個工作查詢,但我覺得它並不像它可能是有效的。虐待繼續解釋:提高我的查詢效率 - 減少全表掃描?

我有一個車表和carEvent表。車表僅存儲汽車的製造商,型號等信息。 CarEvent表存儲汽車發生的事件,例如汽車已經墜毀或汽車已經修好。如果carEvent表上沒有「CRASHED」狀態存在,那麼它還沒有墜毀。我的查詢所做的是返回所有已經墜毀但未修復的汽車。我編寫它的方式需要對carEvent表進行兩次掃描。

我想知道的是,有沒有更有效的方法來做這個查詢?

我的查詢如下:

SELECT * 
FROM Car c 
WHERE (select count(ce.id) FROM CarEvent ce 
     where car_id = c.id AND ce.carEventType = 'CRASHED') > 0 
    AND (select count(ce.id) FROM CarEvent ce 
     where car_id = c.id AND ce.carEventType = 'FIXED') = 0 

任何意見是極大的讚賞。

回答

2

呵呵,臭名昭着的count()在子查詢中。你想用exists,不count

SELECT c.* 
FROM Car c 
WHERE EXISTS (select 1 FROM CarEvent ce where ce.car_id = c.id AND ce.carEventType = 'CRASHED') AND 
     NOT EXISTS (select 1 FROM CarEvent ce where ce.car_id = c.id AND ce.carEventType = 'FIXED'); 

出於性能考慮,你想對CarEvent(car_id, carEventType)的索引。另外,特別要確保在相關的子查詢中使用表別名。

+0

非常感謝您的答覆和對不起我遲到回覆。這個答案很完美。感謝還貢獻了其他人。 – J145

1

使用EXISTSNOT EXISTS

SELECT * FROM Car c 
WHERE EXISTS (select 1 FROM CarEvent ce 
       where car_id = c.id AND ce.carEventType = 'CRASHED') 
    AND NOT EXISTS (select 1 FROM CarEvent ce 
        where car_id = c.id AND ce.carEventType = 'FIXED') 
1

的聯接可以從二對一利用GROUP BYHAVING減少數量:

select Car.id 
from Car 
join CarEvent on Car.id = CarEvent.car_id 
group by Car.id 
having 
    sum(case when carEventType = 'CRASHED' then 1 else 0 end) > 0 
    and 
    sum(case when carEventType = 'FIXED' then 1 else 0 end) = 0