确定分配给用户的实体的数据库性能

时间:2011-11-17 20:08:38

标签: sql sql-server performance

我对以下实例中提高效果的洞察力感兴趣:

我目前正在开发一个具有分层实体结构的应用程序,根据用户在组织内的级别,他们将在特定级别对特定实体进行分配 - 从而可以访问所有子级(在这种情况在美国各地区内的建筑物内。大多数超级用户的投资组合中将有20,000个单独的实体,其中一些实体多达40,000个。

让我们足以说明需要一些逻辑来确定用户有权访问的所有实体,而不是详细说明。目前使用在95%的存储过程中使用的表函数来处理此逻辑。平均存储过程运行时间不超过1-2秒。但是,在ASP.Net页面中调用10多个不同的存储过程,性能迅速下降到20秒以上。

作为替代方案,我们考虑只调用此表函数一次(登录时)并将结果存储在表中(在清除同一用户的任何先前值之后)。然后我们将所有存储过程引用此新表而不是表函数。测试显示,从新表中选择时,用了15秒钟加载的页面可以在不到3秒的时间内呈现。

例如:

  1. 用户登录
  2. 系统删除表中用户的所有实体
  3. 系统会插入所有用户的实体
  4. 系统以快乐的方式发送它们,不再运行当前会话的表函数
  5. 我们担心的是,由于数百名用户可能会一直登录和退出应用程序,因此,由于行级别锁定,删除和插入此表通常会导致性能显着下降。有没有其他人以这种方式使用SQL表?如果是这样,我们是否应该关注由于从单个表中不断插入和删除而导致的低性能。

2 个答案:

答案 0 :(得分:2)

我已经做了类似的事情并且很好但是它适用于最多只有几百个并发用户的应用程序,所以这取决于你拥有什么样的规模。如果你遇到死锁,你可以通过为每个用户创建和删除一个表来进一步使用它,但是当用户的会话到期时你必须有一些东西会丢弃表。

以上两点都是一个黑客攻击,你应该做的是维护用户权限表并在关联数据更改时更新它。根据您的应用,可能需要重新考虑因素。

答案 1 :(得分:2)

我认为这将是一个糟糕的设计,你会在某些时候遇到性能问题。

我可以想到两种方法来解决这个问题,首先你经常需要一个用户可以访问的所有实体的列表,用CTE递归树会快得多检查他们想要访问的记录的权限,但这是模型中的一个重大变化。

第二种方法是在用户登录时更新缓存,但是在更改数据时。在分配表上有一个触发器,每当此数据更改时,将此更改的结果应用于允许的项目表,从而有效地将更改一直级联到树中。因为数据只会在必要时发生变化,所以性能会更高。