搜索多(1-n)个关系表

时间:2011-08-08 16:27:43

标签: mysql sql performance join

当我需要将序列化数据存储在表格中时,我学到了很难的方法。

所以我制作了3张桌子作为基础&两个1-n关系表。

enter image description here

所以这是我想要选择特定活动的查询。

SELECT
jdc_organizations_activities.id
FROM
jdc_activity_sector ,
jdc_activity_type
INNER JOIN jdc_organizations_activities ON jdc_activity_type.activityId = jdc_organizations_activities.id 
AND 
jdc_activity_sector.activityId = jdc_organizations_activities.id
WHERE
jdc_activity_sector.activitySector = 5 AND
jdc_activity_type.activityType = 3

问题:

1-我可以在1-n关系表上添加哪种索引,我已经拥有(activityId - activitySector)&的唯一组合。 (activityId - activityType)

2-是否有更好的方法来编写查询以获得更好的性能?

谢谢!

2 个答案:

答案 0 :(得分:3)

我会重新组织查询以避免使用,表示法导致的交叉产品。

此外,您实际上只使用sectortype表作为过滤器。所以先放activity表,然后加入其他表。

有些人可能会建议;理想情况下,第一个连接最应该是最有可能限制结果的连接,而在第二个连接中留下最少量的工作。实际上,sql引擎实际上可以在生成计划时重新排列您的查询,但它确实有助于您考虑这种方式来帮助您考虑sql引擎必须付出的努力。

最后,每个表都有索引。我实际上建议撤销索引......
- ActivitySector那么ActivityId
- ActivityType THEN ActivityId

这是因为sql引擎正在操纵您的查询。它可以采用WHERE子句并说“只包括Sector表中ActivitySector = 5的记录”,类似于Type表。通过让Sector和Type在索引中识别FIRST,可以更快地完成对表的过滤,然后连接的工作量就会少得多。

SELECT
  [activity].id
FROM
  jdc_organizations_activities    AS [activity]
INNER JOIN
  jdc_activity_sector             AS [sector]
    ON [activity].id = [sector].activityId
INNER JOIN
  jdc_activity_type               AS [type]
    ON [activity].id = [type].activityId
WHERE
  [sector].activitySector = 5
  AND [type].activityType = 3

或者,因为您实际上并未使用Activity表的内容......

SELECT
  [sector].activityId
FROM
  jdc_activity_sector             AS [sector]
INNER JOIN
  jdc_activity_type               AS [type]
    ON [sector].activityId = [type].activityId
WHERE
  [sector].activitySector = 5
  AND [type].activityType = 3

或者...

SELECT
  [activity].id
FROM
  jdc_organizations_activities    AS [activity]
WHERE
  EXISTS (SELECT * FROM jdc_activity_sector WHERE activityId = [activity].id AND activitySector = 5)
  AND EXISTS (SELECT * FROM jdc_activity_type WHERE activityId = [activity].id AND activityType = 3)

答案 1 :(得分:1)

我建议不要在一个查询中混合使用旧样式from table1, table2和新样式from table1 inner join table2 ...。您可以使用table1 as t1对表进行别名,将长表名缩短为易于记忆的简单名称:

select    a.id
from      jdc_organizations_activities a
join      jdc_activity_sector as
on        as.activityId = a.Id
join      jdc_activity_type as at
on        at.activityId = a.Id
where     as.activitySector = 5
          and at.activityType = 3

使用IN更具可读性:

select    a.id
from      jdc_organizations_activities a
where     a.id in 
          (
          select  activityId 
          from    jdc_activity_sector 
          where   activitySector = 5
          )
          and a.id in 
          (
          select  activityId 
          from    jdc_activity_type 
          where   activityType = 3
          )