考虑一个由多个表组成的视图...例如v_active_car
,它由加入car
,body
,{engine
的表格wheels
组成。 {1}}和stereo
。它可能看起来像这样:
v_active_cars
查看
SELECT * FROM car
INNER JOIN body ON car.body = body.body_id
INNER JOIN engine ON car.engine = engine.engine_id
INNER JOIN wheels ON car.wheels = wheels.wheels_id
INNER JOIN stereo ON car.stereo = stereo.stereo_id
WHERE car.active = 1
AND engine.active = 1
AND wheels.active = 1
AND stereo.active = 1
汽车的每个部件都有一个“活动”标志。
现在,我需要找到活动车中可用的所有立体声音响。
要做到这一点,需要使用整个视图,而不仅仅是stereo
表 - 只是因为立体声处于活动状态并不意味着它可以在汽车中使用。
所以我可以做到
SELECT DISTINCT stereo_id FROM v_active_cars
即使这可能会返回非常少量的行,但它仍然是一个非常慢的查询。
我试过这个,但它甚至更慢了:
SELECT stereo_id FROM stereo WHERE EXISTS
(SELECT 1 FROM v_active_cars WHERE stereo_id = stereo.stereo_id)
我还能做些什么来加快速度吗?
答案 0 :(得分:1)
你好像做得对。下一步是检查索引覆盖率。
答案 1 :(得分:1)
答案 2 :(得分:0)
试试这个:
SELECT stereo_id
FROM stereo s, (
SELECT *
FROM v_active_cars
ORDER BY stereo_id
) v
WHERE s.active = 1
AND v.stereo = s.stereo_id
ORDER BY
这里应该阻止将谓词推入视图,优化器应该选择散列连接。
答案 3 :(得分:0)
您可以尝试为每个仅显示活动部分的部分创建视图,然后加入这些视图。例如。
VIEW activeCar
SELECT * FROM car WHERE car.active = 1
VIEW activeEngine
SELECT * FROM engine WHERE engine.active = 1
然后你的最终观点可以是
SELECT * FROM activeCar
INNER JOIN activeEngine ON activeCar.engine = activeEngine.engine_id
显然,请确保您在活动列上有索引。
另一种方法是在id和active标志上都有一个索引。然后,您可以在加入时执行active = 1。这样,只有一个索引用于连接,而不是一个用于id,一个用于活动。
SELECT * FROM car
INNER JOIN body ON car.body = body.body_id AND body.active = 1
INNER JOIN engine ON car.engine = engine.engine_id AND engine.active = 1
INNER JOIN wheels ON car.wheels = wheels.wheels_id AND wheels.active = 1
INNER JOIN stereo ON car.stereo = stereo.stereo_id AND stereo.active = 1