I have a performance-problem with a query in my application and I don’t understand the behavior of mysql.
The query consists of different joins, especially the join to the mentioncache-table. If the join to the mentioncache-table is a simple join, the query takes about three seconds (for a profile which has about 80.000 records in the mentioncache-table). If this join is a straight_join, the query just takes about 0.001 seconds.
The query is:
SELECT SQL_NO_CACHE `Mention`.`id`, `Mention`.`title`, `Mention`.`title_text`, `Mention`.`content_text`, `Mention`.`url`, `Mention`.`root_url`, `Mention`.`sub_type`, `Mention`.`indexed`, `Mention`.`plain_host_url`, `Favoureditem`.`foreign_id`, `Visiteditem`.`foreign_id`, `Visiteditem`.`created`, `Mentionfeedscore`.`score`, Image.id, Image.model, Image.foreign_key, Image.dirname, Image.basename
FROM `mentions` AS `Mention`
LEFT JOIN attachments AS `Image` ON (`Image`.`foreign_key` = `Mention`.`id` AND `Image`.`model` = 'Mention')
LEFT JOIN favoureditems AS `Favoureditem` ON (`Favoureditem`.`model` = "Mention" AND `Favoureditem`.`foreign_id` = `Mention`.`id` AND `Favoureditem`.`owner_id` = 803)
LEFT JOIN visiteditems AS `Visiteditem` ON (`Visiteditem`.`model` = "Mention" AND `Visiteditem`.`foreign_id` = `Mention`.`id` AND `Visiteditem`.`owner_id` = 803)
LEFT JOIN mentionfeedscores AS `Mentionfeedscore` ON (`Mentionfeedscore`.`mention_id` = `Mention`.`id` AND `Mentionfeedscore`.`feed_id` = 'iparkmedia')
STRAIGHT_JOIN mentioncache AS `Mentioncache` ON (`Mentioncache`.`mention_id` = `Mention`.`id` AND `Mentioncache`.`profile_id` = 803)
WHERE `Mention`.`language` = ('de') AND
DATE(`Mention`.`indexed`) BETWEEN "2012-11-04" AND "2012-12-04" AND
`Mention`.`sub_type` IN ('NEWSSITE_TVRADIO', 'NEWSSITE_AGENCY')
ORDER BY `Mention`.`indexed` DESC
LIMIT 0, 10
The explain of this query is:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE Mention index PRIMARY,mention_id,id_indexed,id_sub_type,id_sub_type_indexed,id_sentimentlevel,id_sentimentlevel_indexed indexed 8 NULL 10 Using where
1 SIMPLE Image ref foreign_key,model_foreign_key foreign_key 66 clippingcroc.Mention.id,const 1
1 SIMPLE Favoureditem ref model_foreign_id_owner_id model_foreign_id_owner_id 163 const,clippingcroc.Mention.id,const 1 Using index
1 SIMPLE Visiteditem ref model_foreign_id_owner_id model_foreign_id_owner_id 163 const,clippingcroc.Mention.id,const 1
1 SIMPLE Mentionfeedscore ref mention_id,feed_id mention_id 4 clippingcroc.Mention.id 1
1 SIMPLE Mentioncache eq_ref mention_id_profile_id,mention_id,profile_id mention_id_profile_id 8 clippingcroc.Mention.id,const 1 Using index
The explain for the query with the normal join is:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE Mentioncache ref mention_id_profile_id,mention_id,profile_id profile_id 4 const 133001 Using temporary; Using filesort
1 SIMPLE Mention eq_ref PRIMARY,mention_id,id_indexed,id_sub_type,id_sub_type_indexed,id_sentimentlevel,id_sentimentlevel_indexed PRIMARY 4 clippingcroc.Mentioncache.mention_id 1 Using where
1 SIMPLE Image ref foreign_key,model_foreign_key foreign_key 66 clippingcroc.Mentioncache.mention_id,const 1
1 SIMPLE Favoureditem ref model_foreign_id_owner_id model_foreign_id_owner_id 163 const,clippingcroc.Mentioncache.mention_id,const 1 Using index
1 SIMPLE Visiteditem ref model_foreign_id_owner_id model_foreign_id_owner_id 163 const,clippingcroc.Mentioncache.mention_id,const 1
1 SIMPLE Mentionfeedscore ref mention_id,feed_id mention_id 4 clippingcroc.Mentioncache.mention_id 1
The strange thing is: For a profile which has just has about 400 records in the mentioncache-table, the performance is just the other case around. In this case the query with the normal join takes about 0.015 seconds and for the straight_join about 1,5 seconds. For a profile which has just 5 records in the mentioncache (and no result for the query), the straight_join even takes about 15 seconds (and 0.01 seconds for the normal join).
So why is there such a bad performance when there are less results in the straight_join-case? I don’t understand this.
And what is the best way to get a good performance of this query?
Thanks for some help!
Best regards,
Timo