有可以更改的数据库结构(例如,遗留数据库),我需要对其执行一个附加请求。
数据库结构:
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性能角度来看计算值的最佳方法是什么?拆分为几个更简单的查询还是运行一些复杂的查询?
答案 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万行要计算,也应该非常快。