提高我的查询效率 - 减少完整 table 扫描?
Improving my query efficiency - reducing full table scans?
我想知道您是否可以帮助我解决问题我目前有一个有效的查询,但我觉得它没有达到应有的效率。我继续解释:
我有一辆车 table 和一个 carEvent table。 Car table 只存储汽车的品牌、型号等信息。 CarEvent table 存储发生在汽车上的事件,例如汽车撞毁或汽车已修好。如果给定汽车的 carEvent table 上不存在 "CRASHED" 状态,则它没有坠毁。我的查询所做的是 return 所有已坠毁但未修复的汽车。我写的方式需要对 carEvent table.
进行两次扫描
我想知道的是,是否有更有效的方法来执行此查询?
我的查询如下:
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
非常感谢任何建议。
哦,臭名昭著的 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)
上的索引。此外,请特别确保在相关子查询中使用 table 别名。
使用EXISTS
和NOT 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')
通过使用 GROUP BY
和 HAVING
可以将连接数从两个减少到一个:
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
我想知道您是否可以帮助我解决问题我目前有一个有效的查询,但我觉得它没有达到应有的效率。我继续解释:
我有一辆车 table 和一个 carEvent table。 Car table 只存储汽车的品牌、型号等信息。 CarEvent table 存储发生在汽车上的事件,例如汽车撞毁或汽车已修好。如果给定汽车的 carEvent table 上不存在 "CRASHED" 状态,则它没有坠毁。我的查询所做的是 return 所有已坠毁但未修复的汽车。我写的方式需要对 carEvent table.
进行两次扫描我想知道的是,是否有更有效的方法来执行此查询?
我的查询如下:
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
非常感谢任何建议。
哦,臭名昭著的 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)
上的索引。此外,请特别确保在相关子查询中使用 table 别名。
使用EXISTS
和NOT 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')
通过使用 GROUP BY
和 HAVING
可以将连接数从两个减少到一个:
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