MYSQL:复杂的查询,多个JOIN-s?

时间:2018-09-26 19:33:04

标签: mysql

有可以更改的数据库结构(例如,遗留数据库),我需要对其执行一个附加请求。

数据库结构:

Table "content" (few million rows)
=============================================
║ user_id ║ item_id ║ prop1 ║ prop2 ║ ... ║
=============================================

Table "descriptions" (less than 1 million rows)
========================
║ item_id ║ type ║ ... ║
========================

Table "properties" (multi million rows)
===================
║ prop_id ║ value ║
===================

我需要找到某个特定类型(类型)的用户(user_id)拥有的所有项目,并计算prop1和prop2相乘的总和。
即∑(prop1 * prop2)其中user_id = ...和type = ... 最终结果是一个整数值。

问题在于数据被拆分为3个表,我不知道如何将它们联接起来。可能无法通过单个查询来实现。

问题: 从db性能角度来看计算值的最佳方法是什么?拆分为几个更简单的查询还是运行一些复杂的查询?

1 个答案:

答案 0 :(得分:3)

即使您的第一个表似乎没有被规范化,您也应该能够加入正在考虑的两个属性。

select
      c.user_id,
      d.type,
      sum( p1.value * p2.value ) as SumOfP1TimesP2
   from
      content c
         JOIN descriptions d
            on c.item_id = d.item_id
         JOIN properties p1
            on c.prop1 = p1.prop_id
         JOIN properties p2
            on c.prop2 = p2.prop_id
   where
      c.user_id = parmSomeUserIDKey
   group by
      c.user_id,
      d.type

请注意,属性表是两次使用的...每个别名引用对应于主内容表中每个prop1和prop2字段。

如果要查找单个类型,只需将其添加到where子句中即可。

此外,如果您只关心单个数字,并且知道两个ID(相对于类型的描述),则可以通过以下方式进一步简化操作:

select
      sum( p1.value * p2.value ) as SumOfP1TimesP2
   from
      content c
         JOIN properties p1
            on c.prop1 = p1.prop_id
         JOIN properties p2
            on c.prop2 = p2.prop_id
   where
          c.user_id = parmSomeUserIDKey
      AND c.item_id = d.item_id

注意,正如您对性能所做的评论。只要您有良好的索引,您就应该是良好的。我建议以下内容存在。

属性表,您可能已经在(prop_id) 但对于内容表-(user_id,item_id)上的索引…在索引中显式包含两个字段。由于您想要一个用户/项目,因此除非一个用户/项目具有几百万行(我对此表示怀疑),否则它应该非常快。即使一个人/项目有1万行要计算,也应该非常快。