2

我需要将 10,000 到 20,000 个唯一过滤器应用于 50M 行、8 列和适当索引的数据集。

我目前的方法是一次动态地生成和执行这些查询:

var stats = (from a in db.AggregatedStats
             where a.StatType.StartsWith("TOTAL_ITEM")
             select a);

// Add more filters to the WHERE clause

foreach (var stat in stats) { // Process the data }

我相信这种方法称为从 SQL Server 到 MoveNext() 的“流式传输”数据。

将数据缓冲到程序的内存中会更有效吗?

var stats = (from a in db.AggregatedStats
             where a.StatType.StartsWith("TOTAL_ITEM")
             select a).ToList();

然后将过滤器应用于此实体列表:

var result = (from a in stats
              where a.Region.Equals(region)
              select a);

这将有效地将 SQL Server 查询的数量从 10,000 减少到 1。

在这种情况下,与从 10,000 个查询流式传输数据所需的时间相比,将数据集缓冲到程序中是否值得额外的 RAM?

谢谢!

4

2 回答 2

2

我会花一些时间来分析这些过滤器,看看哪些过滤器过滤掉了大部分数据。您可能会发现有 10-20 个过滤器可以过滤掉 95% 的数据。

如果您可以识别过滤掉大部分数据的前 X 个过滤器,那么您可以将带有这些过滤器的查询应用于数据库。您得到的结果将是一组有限的记录,您可以在内存中缓冲和过滤这些记录。

于 2013-03-26T11:32:11.620 回答
2

消极的。将数据库中的枚举推迟到可能的最后一秒会消除您将即将失效的数据推送到内存中(这只会使用于此应用程序的内存膨胀)。这是您当前示例使用的方法(因为它实际上直到foreach开始才被调用)并且应该是最高性能的。

我想你可能会感到困惑;当你写

var stats = (from a in db.AggregatedStats
         where a.StatType.StartsWith("TOTAL_ITEM")
         select a);

实际上没有发生任何事情 -stats只包含一个知道如何获取数据的迭代器,并且在您ToList()使用 a 调用或枚举该查询之前foreach,实际上没有任何请求,这就是您获得性能的原因。

于 2013-03-25T22:06:47.327 回答