使用大量可能的连接进行查询的最佳方法

时间:2013-04-27 13:03:43

标签: mysql sql join

在我正在进行的项目中,我们有一个活动表,每个活动都可以链接到大约20个不同的“活动详细信息”表中的一个......

e.g。如果活动的类型为“work”,那么它将具有相应的activity_details_ work 记录,如果它是“病假”类型,那么它将具有相应的activity_details_ sickleave 记录等。

目前我们正在加载活动,然后对于每个活动,我们都有一个单独的查询来从相关表中获取活动详细信息。如果你有成千上万的活动,这显然不能很好地扩展。

所以我最初想的是有一个查询来获取活动并一次性加入细节,例如

SELECT * FROM activity
LEFT JOIN activity_details_1_work ON ...
LEFT JOIN activity_details_2_sickleave ON ...
LEFT JOIN activity_details_3_travelwork ON ...
...etc...
LEFT JOIN activity_details_20_yearleave ON ...

但这会导致每条记录都有100个字段,其中大部分是空的,感觉很讨厌。

延迟加载细节实际上并不是一个选项,因为核心逻辑中几乎总是要求细节,至少对于主要类型而言。

有没有一种超级聪明的方法可以做到这一点,我没想到?

提前致谢

3 个答案:

答案 0 :(得分:2)

我的建议是为每个ActivityType定义一个视图,该视图专门针对该活动进行定制。

然后在ActivityType字段的Activity表引线上添加一个索引。集群表示索引,除非对其他一些集群的压倒性需求(或性能基准测试显示其他一些集群选择更具性能)。

为什么设计这种程度的非规范化是有特殊原因的吗?这个原因众所周知吗?

答案 1 :(得分:2)

您的活动表可能就像(date_from, date_to, with_who, descr)或类似的东西。正如Pieter建议的那样,考虑在那里抛出一个类型varchar或enum字段,以便处理单个详细信息表。

如果有合理的理由让表格分开,可以考虑添加维护boolean / tinyint字段(has_workhas_sickleave等)或位字符串(has_activites_of_type所在的触发器)第一个位置为has_work,下一个位置为has_sickleave等。)

无论哪种方式,通过在一个或多个单独的查询中获取活动的详细信息,您可能会更好 - 如果只是为了避免字段名称冲突。

答案 2 :(得分:1)

我不认为枚举是可行的,因为正如你所说,可能有1000个活动,那么改变你的activity表将成为一个问题。

没有必要在大量的表上进行左连接。

所以您拥有的选项是:

  1. See this第一条评论可能有用。

  2. 我猜你的活动表有一个名为activity_type_id的字段。 构建一个名为activity_types的表,其中包含字段activity_type_idactivity_nameactivity_details_table_name。首先按以下方式查询

    活性
    内连接 activity_types
    使用(activity_type_id)

  3. 此查询为您提供要查询详细信息的表名。 这样,只需在activity_types表中添加一行即可添加任何新的活动类型。