将“计算临时表中的中间结果”SQL模式调整为LINQ?

时间:2011-11-24 06:36:23

标签: c# linq-to-sql sql-server-2008-r2

我的团队构建了一个C#Web应用程序,可以生成临时报告,以不同的方式重新组合来自同一核心SQL Server 2008 R2表的数据。例如,单个“仪表板”页面可以组合每个区域的今天销售列表,最低销售项目列表及其上周的趋势,最佳销售人员列表以及20多个其他指标和图表。在封面下方,典型的仪表板页面将需要跨20多个不同表格的至少30个查询。

不幸的是,“冻结”这些数据并预先计算它是不切实际的 - 我们需要即时获取实时数据。

为了使这些页面更快,我们的诀窍是识别不同的查询,从而获取相同的基础数据。然后我们计算那些基础表的中间结果,将这些结果缓存到临时表中,然后将该临时表连接到其他表以计算最终结果。使用这种方法,我们通常可以将特定仪表板所需的I / O和时间减少10倍。

我们的团队希望将相同的模式应用于使用LINQ-to-SQL进行数据访问的类似页面。我们喜欢LINQ用于编程易用性,用于单元测试等。但是上面描述的应用程序的性能很糟糕,我们执行可能部分依赖于相同底层数据的多个查询。

当然我可以调用AsEnumerable()来实现中间查询结果,但是如果中间结果很大,那么将结果输入和输出SQL会否定性能获胜并创建带有数百项的低效参数化查询 - 长IN (@p1, ... )条款。

在一个完美的世界中,LINQ-to-SQL将提供一个AsServerEnumerable()方法,该方法将创建一个临时的中间结果表,我可以在不离开数据库的情况下重复使用。

这样的事情存在吗?

如果没有,有什么建议让我们的“服务器端中间实现”模式在LINQ上运行良好吗?

P.S。 - 我说上面是“临时表”而不是“表变量”,因为临时表往往更好地处理更昂贵的查询(并行查询计划,非聚集索引等)。但是否则以上所有内容都适用于表变量。

2 个答案:

答案 0 :(得分:3)

不,这在原始LINQ中不存在,并且在我所知道的任何LINQ风格的API中都没有预先设置。

如果忽略LINQ-to-SQL的“LINQ”部分并且只使用db.ExecuteQuery<T>(sql, args)方法,可以存在,但如果你这样做,你必须注意确保你正在将明确的和open 连接传递给数据上下文(如果使用连接字符串方法,则会自动处理连接管理,并且无法保证在操作之间获得相同的连接 - 它可以从池中获取,因此即使它是相同的底层连接,它也会被重置,丢弃任何临时表。)

答案 1 :(得分:2)

好吧,如果你有很多读取,你可以考虑创建一个VIEW而不是一个临时表,并为该视图添加一个聚簇索引。这将实现数据库中的视图。

  

SQL Server可以通过两种不同的方式使用索引视图。首先,可以直接从查询调用视图,因为当前使用传统视图。但是,它不是运行视图的基础SELECT语句并动态创建视图的结果集,而是使用唯一的聚簇索引几乎立即显示视图的结果。其次,将自动评估在SQL Server 2000/2005上运行的任何查询,以查看是否存在任何可满足查询的现有索引视图。如果是这样,查询优化器使用索引查询,即使它未在查询中指定,也会大大加快查询速度。

更多信息:Sql server performance