Reputation: 147
Running the following query takes forever. All the tables contain more than 200,000 records. Indexes exist on all the columns in the joining statements:
Select files.filename,
coalesce(temp_decmetadata.glare_roadGlare, 0) as glare_roadGlare,
coalesce(temp_decmetadata.glare_sun, 0) as glare_sun,
coalesce(temp_decmetadata.spray_heavySpray, 0) as spray_heavySpray,
coalesce(temp_kafaspdobjectdata.contrast_wellVisible, 0) as contrast_wellVisible,
coalesce(temp_kafaspdobjectdata.roadSafety_zebraCrossing, 0) as roadSafety_zebraCrossing,
coalesce(temp_visionmetadata.roadUser_bicycle, 0) as roadUser_bicycle,
coalesce(temp_visionmetadata.roadUser_car, 0) as roadUser_car,
coalesce(temp_visionmetadata.roadUser_pedestrian, 0) as roadUser_pedestrian
from files
left join
(
Select id,
count(case when glare like '%roadGlare%' then 1 end) as glare_roadGlare,
count(case when glare like '%sun%' then 1 end) as glare_sun,
count(case when spray like '%heavySpray%' then 1 end) as spray_heavySpray
from decmetadata
group by id
) temp_decmetadata on temp_decmetadata.id = files.id
left join
(
Select id,
count(case when contrast like '%wellVisible%' then 1 end) as contrast_wellVisible,
count(case when roadSafety like '%zebraCrossing%' then 1 end) as roadSafety_zebraCrossing
from kafaspdobjectdata
group by id
) temp_kafaspdobjectdata on temp_kafaspdobjectdata.id = files.id
left join
(
Select id,
count(case when roadUser like '%bicycle%' then 1 end) as roadUser_bicycle,
count(case when roadUser like '%car%' then 1 end) as roadUser_car,
count(case when roadUser like '%pedestrian%' then 1 end) as roadUser_pedestrian
from visionmetadata
group by id
) temp_visionmetadata on temp_visionmetadata.id = files.id
Result of "Explain Select..." is attached below:
Upvotes: 2
Views: 628
Reputation: 6703
I'm not a MySQL specialist, but you can sure improve the sub-queries by moving the JOIN condition to the inner WHERE
conditions and filtering the rows to only those that satisfies any CASE
condition, this will decrease the number of rows that must be evaluated by the LIKE
operator (this is the most expensive operation in this query). The following script should give you the idea:
...
CROSS JOIN (
SELECT
SUM(CASE WHEN glare LIKE '%roadGlare%' THEN 1 ELSE 0 END) AS glare_roadGlare,
SUM(CASE WHEN glare LIKE '%sun%' THEN 1 ELSE 0 END) AS glare_sun,
SUM(CASE WHEN spray LIKE '%heavySpray%' THEN 1 ELSE 0 END) AS spray_heavySpray
FROM decmetadata
WHERE ( id = files.id ) -- benefits from an index over DECMETADATA.ID
AND ( 1=2
OR glare LIKE '%roadGlare%'
OR glare LIKE '%sun%'
OR spray LIKE '%heavySpray%'
)
) temp_decmetadata
...
Upvotes: 1
Reputation: 171411
Your query is well-structured. The issue is all of the like '%xxx%'
queries. Indexes will not help those clauses when you are substring matching like that.
Try using full text search instead.
Upvotes: 0