【问题标题】:Searching on multi (1-n) relation tables搜索多 (1-n) 个关系表
【发布时间】:2011-08-08 16:27:43
【问题描述】:

当我需要使其可搜索时,我不应该将序列化数据存储在表中。

所以我将 3 个表作为基础表和两个 1-n 关系表。

如果我想选择一个特定的活动,这是我得到的查询。

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- 有没有更好的方法来编写查询以获得更好的性能?

谢谢!

【问题讨论】:

  • 离题,但我建议您坚持使用 JOIN 语法,不要混合使用旧的 , 语法进行连接。

标签: mysql sql performance join


【解决方案1】:

我会重新组织查询以避免使用, 表示法引起的叉积。

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

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

最后,每个表都有索引。我实际上建议反转索引...
- ActivitySector THEN ActivityId
- ActivityType THEN ActivityId

这特别是因为 sql 引擎正在操纵您的查询。它可以使用 WHERE 子句并说“仅包括 ActivitySector = 5 的 Sector 表中的记录”,对于 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,但你不应该使用 [ ] 语法,因为这不适用于 mysql,在这种情况下,在 mysql 中子查询也是一个坏主意。
【解决方案2】:

我建议不要在单个查询中混合旧样式 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
          )

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-30
    相关资源
    最近更新 更多