Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net 缓存SELECT语句的结果以便在多个查询中重用_Asp.net_Sql Server_Performance - Fatal编程技术网

Asp.net 缓存SELECT语句的结果以便在多个查询中重用

Asp.net 缓存SELECT语句的结果以便在多个查询中重用,asp.net,sql-server,performance,Asp.net,Sql Server,Performance,我有一个相当复杂的查询,根据用户输入的参数提取我感兴趣的结果的Id字段 提取相关ID后,我在单独的查询中多次使用生成的ID集来提取我想要的实际输出记录集(通过连接到其他表、使用聚合函数等) 我希望避免为要返回的每一组结果分别运行初始查询。我想我的情况是一种常见的模式,所以我对最好的方法感兴趣 数据库位于MS SQL Server中,我使用的是.NET 3.5。对于SQL Server,Microsoft通常建议在可行的情况下使用存储过程 以下是一些优点: 还值得注意的是,与其他RDBMS供应商

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

提取相关ID后,我在单独的查询中多次使用生成的ID集来提取我想要的实际输出记录集(通过连接到其他表、使用聚合函数等)

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


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

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

以下是一些优点:

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

但是,对于SQL Server的最后两个版本,执行 对于所有T-SQL批处理,无论是否 它们位于存储过程中


最好的方法取决于Id更改的频率,或者您希望再次查找它的频率

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

此主题有许多可能的变体。

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

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


如果计划在SQL Server中执行同样的操作,可以考虑使用索引视图来查找ID。视图将具体化,因此您可以更快地获得结果。你甚至可以考虑使用一个临时表来临时保存ID。

你查询的数据变化频繁吗?对我来说,这听起来像是一个完美的数据仓库场景,您可以将数据扁平化以更快地检索数据,并完全按照“DTO”希望看到的数据创建表。此方法与索引视图的不同之处在于,它只是一个具有快速查找操作的表,如果您在计划查询的列上正确设置索引,则尤其可以改进此方法。

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

如果缓存ID集的所有使用都包括将整个ID集连接到其他表,那么解决方案绝对不应该涉及在数据库之外缓存ID集。如果可以避免,数据不应该来回移动

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

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

索引视图明显优于临时表,除非底层数据在整个过程中是只读的,或者您可以并且希望忽略这些更新以保持整个报告集的一致性。然而,索引视图始终准确地投影底层数据的能力是以减慢更新速度为代价的

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

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


最后但并非最不重要的一点是,确保在重新填充数据库时(以及在生产中的夜间)使用
更新统计信息
,否则您的查询优化器将无法将您创建的索引发挥最佳作用。

您可以创建
全局临时表
。动态创建表格。现在根据您的要求插入记录。在联接中的下一个请求中访问此表。。。为了重用SQL Server 2008,您可以将表变量作为参数传递给SQL。只需缓存ID,然后将其作为表变量传递给获取数据的查询。此应用程序的唯一警告
* 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
this.Cache["key"] = "value";