SELECT语句的缓存结果,可在多个查询中重用

时间:2012-01-19 06:15:29

标签: asp.net sql-server performance

我有一个相当复杂的查询来根据用户输入的参数提取我感兴趣的结果的Id字段。

在提取相关的ID之后,我在不同的查询中多次使用得到的Ids集合来提取我想要的实际输出记录集(通过连接到其他表,使用聚合函数等)。

我想避免为我想要返回的每组结果单独运行初始查询。我想我的情况是一种常见的模式,所以我对最好的方法感兴趣。

数据库在MS SQL Server中,我使用的是.NET 3.5。

8 个答案:

答案 0 :(得分:1)

如果您计划在应用程序代码中缓存结果集,那么ASP.NET具有缓存,您的Winform将使用该对象保存数据,您可以使用该数据重用数据。

如果计划在SQL Server中执行相同操作,您可以考虑使用索引视图来查找Id。视图将实现,因此您可以更快地获得结果。您甚至可以考虑使用临时表暂时保存ID。

答案 1 :(得分:1)

如果问题包含对未经优化的解决方案(数据大小,时间)的一些测量,那肯定会有所帮助。这里可以考虑各种技术,其中一些在其他答案中列出。我将假设您不希望重复运行相同查询的原因是性能。

如果缓存ID集的所有用途都包含整个集合到其他表的连接,那么解决方案绝对不应该涉及在数据库之外缓存ID集。如果可以避免,数据不应该再往返于那里。

在某些情况下(当不涉及游标或极其复杂的SQL时)最好(即使是违反直觉的)不执行缓存并简单地将重复SQL连接到所有期望的查询。毕竟,每个查询都需要根据其中一个连接表进行遍历,然后性能在很大程度上取决于加入和快速评估所有剩余信息所需的索引的可用性。

在数据库中“缓存”ID集的最直观方法是临时表(如果命名为#something,它对于连接是私有的,因此可以由并行独立客户端使用;或者可以命名##something并且是全球性的。如果表将有许多记录,则索引是必需的。为了获得最佳性能,索引应该是聚簇索引(每个表只允许一个),或者只在构造该集合后创建,其中索引创建稍快一些。

索引视图比临时表更可取,除非在整个过程中只读取基础数据,或者您可以并且希望忽略此类更新以使整个报表集保持一致。但是,索引视图始终准确地投影基础数据的能力是以降低这些更新为代价的。

这个问题的另一个答案提到了存储过程。这主要是组织代码的一种方式。但是,如果你这样做,最好避免使用临时表,因为对临时表的这种引用会阻止预编译存储过程;如果可以,请查看视图或索引视图。

无论您选择何种方法,都不要猜测性能特征和查询优化器行为。学习显示查询执行计划(在SQL Server Management Studio中),并确保您看到索引访问,而不是嵌套循环组合多个大型数据集;只添加可明显且彻底改变查询性能的索引。精心挑选的索引通常可以将查询的性能改变1000倍,因此学习起来有点复杂,但对成功至关重要。

最后但并非最不重要的是,确保在重新填充数据库时(以及每晚生产中)使用UPDATE STATISTICS,否则您的查询优化器将无法将您创建的索引用于最佳用途。 / p>

答案 2 :(得分:1)

使用SQL Server 2008,您可以将表变量作为参数传递给SQL。只需缓存ID,然后将它们作为表变量传递给获取数据的查询。这种方法唯一需要注意的是,您必须将表类型预定义为UDT。

http://msdn.microsoft.com/en-us/library/bb510489.aspx

答案 3 :(得分:0)

对于SQL Server,Microsoft通常建议在可行的情况下使用存储过程。

以下是一些优点:

  

http://blog.sqlauthority.com/2007/04/13/sql-server-stored-procedures-advantages-and-best-advantage/

* Execution plan retention and reuse
* Query auto-parameterization
* Encapsulation of business rules and policies
* Application modularization
* Sharing of application logic between applications
* Access to database objects that is both secure and uniform
* Consistent, safe data modification
* Network bandwidth conservation
* Support for automatic execution at system start-up
* Enhanced hardware and software capabilities
* Improved security
* Reduced development cost and increased reliability
* Centralized security, administration, and maintenance for common routines

值得注意的是,与其他RDBMS供应商(例如Oracle)不同,MSSQL会自动缓存所有执行计划:

  

http://msdn.microsoft.com/en-us/library/ms973918.aspx

     

但是,对于最后几个版本的SQL Server,执行   无论是否为所有T-SQL批次缓存计划   它们在存储过程中

答案 4 :(得分:0)

最佳方法取决于ID更改的频率,或者您希望再次查找的频率。

一种技术是使用Cache对象(也可以从HttpRuntime.Cache访问)将结果存储在ASP.NET对象缓存中。例如(来自页面):

this.Cache["key"] = "value";

这个主题有很多可能的变化。

答案 5 :(得分:0)

您可以使用Memcached缓存内存中的值。 正如我看到there are一些.net端口。

答案 6 :(得分:0)

您要查询的数据更改频率如何?对我来说,这听起来像是数据仓库的完美场景,在这种情况下,您可以平滑数据以便更快地检索数据,并创建与“DTO”想要查看数据完全相同的表格。此方法与索引视图不同,因为它只是一个具有快速搜索操作的表,如果您在计划查询的列上正确设置索引,则可以进行特别改进

答案 7 :(得分:0)

您可以创建Global temporary Table。动态创建表。现在根据您的请求插入记录。在您的联接中的下一个请求中访问此表...以获得可重用性