我有一个关于如何优化查询的问题。实际上,由于我要经常运行查询,我正在考虑使用物化视图或索引视图(这是一个好主意吗?)或非规范化。
考虑以下四个表(省略了不相关的字段):
- 用户(int userId)
- 组(int groupId)
- GroupMemberships (int userId, int groupId, bool isSharing)
- 计算机(int userId)
关系是一个用户可以拥有 0..n 台计算机(一个用户对多台计算机)并且可以是 0..n 个组的成员。一个组可以有 0..n 个用户(许多用户对许多组)。“isSharing”表示用户是否正在与该组共享,或者是该组的“只读”成员(即,可以看到共享成员的计算机,但不能共享她自己的)。
查询是为给定用户查找该用户可以看到哪些计算机。用户可以看到她自己的所有计算机。她还可以查看属于她的成员并与该组共享的组中的其他用户的任何计算机。好的,这没有多大意义,所以这是 O(n^3) psudocode 中的目标:
List<Computer> l
foreach(Computer c in Computers)
if(c.userId == current_user_id)
add c to l
else
foreach(GroupMembership m where m.userId == current_user_id)
foreach(GroupMembership m2 where c.userId == m2.userId && m.groupId == m2.groupId)
if(m2.isSharing)
add c to l
现在我正在使用 ORM 映射器并基本上执行上述操作(我对整个 SQL 事情不太擅长),但这显然是一个不太理想的解决方案。我在此处列出的每个字段(isShared 除外)上都有索引,在 GroupMembership 的 (userId, groupId) 元组上有一个额外的索引。但是那里的任何数据库向导都可以想到更好的解决方案吗?
该项目尚未上线,但我猜每个用户平均可能有 1.2 台计算机(每个人都有一台,少数人可能有更多),每个用户可能有 0.75 个组成员资格(许多用户不会使用这些组功能,但这样做的人可能是多个组的成员)。此外,所有这些关联的表都将频繁添加,这可能会使物化视图成为不太实用的解决方案。我正在使用 SQL Server 2008。
谢谢,一切顺利,罗伯特