Consider a view consisting of several tables... for example a v_active_car
, which is made up of the tables car
joined on to body
, engine
, wheels
and stereo
. It might look something like this:
v_active_cars
view
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
Each component of the car has an "active" flag.
Now, I need to find all the stereos that are available in active cars.
To do this in need to use the whole view, not just the stereo
table - just because a stereo is active doesn't mean it's available in a car.
So I can do
SELECT DISTINCT stereo_id FROM v_active_cars
Even though this may return a very small number of rows, it's stil a very slow query.
I've tried this, but it's even slower:
SELECT stereo_id FROM stereo WHERE EXISTS
(SELECT 1 FROM v_active_cars WHERE stereo_id = stereo.stereo_id)
Is there anything else I could do to make this faster?
The following recommendations will help you in your SQL tuning process.
You'll find 3 sections below:
ALTER TABLE `body` ADD INDEX `body_idx_body_id` (`body_id`);
ALTER TABLE `car` ADD INDEX `car_idx_active` (`active`);
ALTER TABLE `engine` ADD INDEX `engine_idx_active_engine_id` (`active`,`engine_id`);
ALTER TABLE `stereo` ADD INDEX `stereo_idx_active_stereo_id` (`active`,`stereo_id`);
ALTER TABLE `wheels` ADD INDEX `wheels_idx_active_wheels_id` (`active`,`wheels_id`);
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