MYSql 查询 - #2013 - 查询期间丢失与 MySQL 服务器的连接

标签 mysql join indexing

我有一个包含多个连接的长查询,该查询已超时。我已经在所有赞助商表中创建了 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 是下一个表,它需要以某种方式进入。听起来好像 EventIdPRIMARY 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/

相关文章:

sql-server - SQL : JOIN value from table A with table C if table B is empty

php - Mysql join 用于以下ER

indexing - 如何向现有的开放 Lucene 索引添加新文档

indexing - iTunes 商店 : App keyword search optimization. 字符串智能索引?

php - 行分页时如何检索列总数?

mysql - 将 3 个查询优化为一个查询的最佳方法

mysql - 检索特定月份的数据

mysql - SQL: N-N Select * from table1 并检测是否与特定用户 ID 的另一个存在关系

database - 如何在 Grails 中使用 Hibernate 索引?

mysql - 带有 where 子查询的 Select 语句返回多行以检查是否包含在另一个子查询中