我有一个包含多个连接的长查询,该查询已超时。我已经在所有赞助商表中创建了 Sponsor_Id
(在 WHERE
中使用)作为索引。分析器图表显示速度极其缓慢(发送数据的时间为 75%)。
这是查询:
SELECT GROUP_CONCAT(DISTINCT masterdetail.eventid) as eventids
FROM tblsponsor_slave_eventprefrencesdetail userprefrence
INNER JOIN tblsponsor_slave_sponsor_eventprefrence_category
userprefcategory
ON userprefrence.SponsorId = userprefcategory.SponsorId
INNER JOIN tblsponsor_slave_sponsor_eventprefrence_locationtarget
userpreflocation
ON userprefrence.SponsorId = userpreflocation.SponsorId
INNER JOIN tblsponsor_slave_sponsor_eventprefrence_type userprefEventType
ON userprefrence.SponsorId = userprefEventType.SponsorId
INNER JOIN tblsponsor_slave_sponsor_eventprefrence_audienceprofile
userprefAudiProfile
ON userprefrence.SponsorId = userprefAudiProfile.SponsorId
INNER JOIN tblsponsor_slave_sponsor_eventprefrence_industry
userprefIndustry
ON userprefrence.SponsorId = userprefIndustry.SponsorId
INNER JOIN tblsponsor_slave_eventprefrencesdetail userprefdetail
ON userprefrence.SponsorId = userprefdetail.SponsorId
INNER JOIN tblsponsor_slave_sponsor_eventprefrence_audiencetype
userprefAudiType
ON userprefrence.SponsorId = userprefAudiType.SponsorId
INNER JOIN tblsponsor_slave_eventprefrence_agegroup userprefAgeGroup
ON userprefrence.SponsorId = userprefAgeGroup.SponsorId
INNER JOIN tblevent_slave_event_address_city eventcity
ON userpreflocation.Sponsor_EventPrefrence_LocationTarget =
eventcity.Event_Address_City
INNER JOIN tblevent_slave_event_audienceprofile eventAudiProfile
ON userprefAudiProfile.Sponsor_EventPrefrence_AudienceProfile =
eventAudiProfile.Event_AudienceProfile
INNER JOIN tblevent_slave_event_industrycatered eventindustry
ON userprefIndustry.Sponsor_EventPrefrence_Industry =
eventindustry.Event_IndustryCatered
INNER JOIN tblevent_slave_agegroup eventagegroup
ON userprefAgeGroup.Sponsor_AgeGroup_Type =
eventagegroup.Event_AgeGroup_Type
AND userprefAgeGroup.IsExist = eventagegroup.IsExist
INNER JOIN tblevent_master_detail masterdetail
ON eventcity.EventId = masterdetail.EventId
INNER JOIN tblevent_slave_others eventothers
on masterdetail.EventId = eventothers.EventId
AND masterdetail.Event_Category =
userprefcategory.Sponsor_EventPrefrence_Category
AND masterdetail.Event_Type =
userprefEventType.Sponsor_EventPrefrence_Type
AND eventothers.Event_Gender =
userprefdetail.Sponsor_EventPrefrence_Gender
AND eventothers.Event_TargetAudience =
userprefAudiType.Sponsor_EventPrefrence_AudienceType
AND eventothers.Event_Sponsor_Range_Min <
userprefrence.Sponsor_EventPrefrence_Range_Max
WHERE userprefrence.SponsorId = 164
AND eventagegroup.IsExist = 1
AND masterdetail.Event_StartDateTime > '2015-08-27'
AND masterdetail.Event_Category in ( "1", "2", "3", "7",
"9", "10", "11" )
AND eventcity.Event_Address_City in ( "1", "3", "54" )
AND masterdetail.Event_Type in ( "2", "3", "4", "5", "7" )
AND eventindustry.Event_IndustryCatered in ( "13", "18" )
AND eventAudiProfile.Event_AudienceProfile in ( "1", "2", "10" )
最佳答案
优化器(可能)将从按 WHERE
子句中的内容进行最佳过滤的表开始。哪个看起来最有选择性?假设它是 masterdetail.Event_StartDateTime > '2015-08-27'
。然后,您需要在 masterdetail
上建立一个索引,从 Event_StartDateTime
开始。
然后它将移动到其他表。它可能会看到:
ON eventcity.EventId = masterdetail.EventId
暗示 eventcity
是下一个表,它需要以某种方式进入。听起来好像 EventId
是 PRIMARY KEY
;因此无需采取进一步行动。
然后到下一张 table 。还有下一个。等等
这些 WHERE
子句需要一些讨论:
userprefrence.SponsorId = 164
eventagegroup.IsExist = 1
它们是列 = 常量,这使得它们非常适合索引。另一方面,IsExist
闻起来像一个真/假标志,它本身在索引中几乎从来没有用处。
无论如何,拥有一个包含字段和正在JOINed
的字段的复合索引可能会很有用。 p>
你能证明 15 个表的 JOIN
合理吗?那是很多。 (“正常化,但不要过度正常化。”)
我很盲目——你能为每个提供SHOW CREATE TABLE
(在实现了我的建议之后)吗?
我给你的可能并不是你能做的全部。
发送数据
是无用的信息;他们需要以某种方式分解它。
关于MYSql 查询 - #2013 - 查询期间丢失与 MySQL 服务器的连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32258310/