Sql server 2005 &引用;索引;在SQLServer2005中(也称为维护)聚合数据表

Sql server 2005 &引用;索引;在SQLServer2005中(也称为维护)聚合数据表,sql-server-2005,group-by,aggregate-functions,Sql Server 2005,Group By,Aggregate Functions,我有一个表,用于维护系统的性能数据,每个记录都是对某个重要方法的调用,包括方法名称、持续时间和令牌-对系统的每个请求都有一个唯一的令牌,因此具有相同令牌的所有记录都是相同的请求,例如: CallName Duration Token ----------- ----------- ----------- GetData 121 12345 Process 800 12345 SaveData 87 12345

我有一个表,用于维护系统的性能数据,每个记录都是对某个重要方法的调用,包括方法名称、持续时间和令牌-对系统的每个请求都有一个唯一的令牌,因此具有相同令牌的所有记录都是相同的请求,例如:

CallName    Duration    Token
----------- ----------- -----------
GetData     121         12345
Process     800         12345
SaveData    87          12345

GetData     97          ABCDE
Process     652         ABCDE
SaveData    101         ABCDE
我对按令牌和调用名分组的聚合数据感兴趣,例如:

-- The total duration of each request, in descending order
SELECT Token, SUM(Duration) FROM Requests GROUP BY Token ORDER BY SUM(Duration) DESC

-- The average duration of each call, in descending order
SELECT CallName, AVG(Duration) FROM Requests GROUP BY CallName ORDER BY AVG(Duration) DESC
现在这个表可能非常大,我只对每个查询的前几条记录感兴趣,所以我为这两个查询实现了分页。问题在于,由于这些查询涉及聚合函数,SQL server最终还是执行了表扫描

其他人以前肯定有过这个问题吗

这里我真正需要的是一个按令牌分组的总和(持续时间)的“索引”,即一个我可以执行以下操作的表:

SELECT Token, SumToken FROM RequestTokens ORDER BY SumToken DESC
  • 这真的是个坏主意吗
  • 如果是,有没有更好的办法
  • 最好的方法是什么?INSERT/UPDATE/DELETE上的触发器是否有效(我根据旧值和更改的数据更新聚合值),或者在更新此表时手动更新“索引”是否更好

触发器是迄今为止我提出的最佳解决方案,但我已经看到这是一场死锁/一致性噩梦!:-首先,令牌列上的索引是否足够?这样,给定令牌值,SQL查询优化器将只扫描包含您感兴趣的行的索引部分。将其作为聚集索引,您将获得最佳性能


接下来,您如何知道您对聚合哪个令牌值感兴趣?没有列出datetime(或timestamp)列,而且标记值似乎是随机分配的(与某种形式的升序值相反),因此我猜您在发出查询之前知道要聚合的标记值——在该查询中,索引应该做您想要做的事。如果值未知,但以某种方式递增,则可以使用多种策略首先确定最新的X标记值,一旦获得该/这些标记,您将返回部分表扫描。

首先,标记列上的索引是否足够?这样,给定令牌值,SQL查询优化器将只扫描包含您感兴趣的行的索引部分。将其作为聚集索引,您将获得最佳性能


接下来,您如何知道您对聚合哪个令牌值感兴趣?没有列出datetime(或timestamp)列,而且标记值似乎是随机分配的(与某种形式的升序值相反),因此我猜您在发出查询之前知道要聚合的标记值——在该查询中,索引应该做您想要做的事。如果值未知,但以某种方式递增,则可以使用多种策略首先确定最新的X标记值,一旦获得这些标记,就可以返回部分表扫描。

基于聚合的视图如何,甚至可能是索引视图。我在索引视图方面做得不多,但本文讨论了如何将它们用于复杂的聚合,如AVG()。也许这会让你走上正确的方向


基于聚合的视图如何,甚至可能是索引视图。我在索引视图方面做得不多,但本文讨论了如何将它们用于复杂的聚合,如AVG()。也许这会让你走上正确的方向


既然我更了解这一点,我就再试试看。这是一个常见的报告问题,导致了数据仓库解决方案,就像这样:您可以只添加第二个包含预聚合数据的表吗?这确实是非规范化/冗余数据。。。但它似乎清晰、定义明确,并满足业务需求。在这个想法上有几条皱纹:

如果数据只输入一次,是否可以修改数据输入例程以同时添加聚合行。如果随着时间的推移,它会慢慢出现,你需要一个反复的过程来“扫除一切”。我根据一般原则避免触发;它们在这方面可能会有所帮助,但也可能会根据使用模式和数据相互关系来连接您的系统

数据必须是最新的吗?聚合数据是否会与详细数据不同步?如果是,会持续多长时间?您可以有一个SQL代理作业,每天/小时/5分钟运行,以扫描最近的条目并更新聚合表。(添加一个索引的“last entered”列,这些更新可能会很快完成。)权衡的是数据关闭的时间段。(但datetime列可能表示“截至何时”数据是准确的。可能您没有在该时间点之后提供聚合数据?)


如果数据输入后没有更改(没有更新,没有删除,没有延迟到达的行),这可能会起作用——但是如果您必须随着时间的推移保持更新,并且聚集的数据更改必须在输入数据的同时可用,那么维护可能会是一场噩梦。

我将再次尝试这一点,现在我更明白了。这是一个常见的报告问题,导致了数据仓库解决方案,就像这样:您可以只添加第二个包含预聚合数据的表吗?这确实是非规范化/冗余数据。。。但它似乎清晰、定义明确,并满足业务需求。在这个想法上有几条皱纹:

如果数据只输入一次,是否可以修改数据输入例程以同时添加聚合行。如果随着时间的推移,它会慢慢出现,你需要一个反复的过程来“扫除一切”。我根据一般原则避免触发;他们可能会在这里帮忙,但他们也可以合作